2012-03-19 5 views
10

Sto cercando di utilizzare PKCS5_PBKDF2_HMAC_SHA1() e di seguito è il mio programma di esempio. Volevo essere sicuro che il mio risultato di PKCS5_PBKDF2_HMAC_SHA1() fosse corretto, quindi ho verificato la stessa cosa con il sito web http://anandam.name/pbkdf2/ e vedo un risultato diverso. Sto usando l'API correttamente?Come utilizzare PKCS5_PBKDF2_HMAC_SHA1()

Ho dubbi se sto passando correttamente il valore del sale.

Ho incollato il risultato e il risultato del sito Web dopo il programma.

Per favore aiutami a capire questo.

#include <stdio.h>  
#include <types.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

#include <malloc.h> 

#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <openssl/engine.h> 
#include <openssl/aes.h> 
#include <openssl/rand.h> 

#include <proto.h> 
#define KEY_LEN 32// 32 bytes - 256 bits 
#define KEK_KEY_LEN 5 
#define ITERATION 1000 

unsigned char salt_value[KEY_LEN]; 
unsigned char AESkey[KEY_LEN]; 
unsigned char XTSkey[KEY_LEN]; 
u8 fuse_key[KEY_LEN]; 

void main() 
{ 
    s32 i=0; 
    s32 len =0; 
    u8 *out; 
    u8 *rspHMAC; 
    const s8 pwd[] = "test"; 
    s8 rspPKCS5[KEK_KEY_LEN * 2]; 
    s32 ret; 

    rspHMAC = (unsigned char *) malloc(sizeof(char) * KEY_LEN); 
    out = (unsigned char *) malloc(sizeof(char) * KEK_KEY_LEN); 

    RAND_bytes(salt_value, KEY_LEN); 

    printf("\n salt_value[0] = %x; salt_value[31]= %x", salt_value[0], salt_value[31]); 
    printf("\n strlen(salt_value) = %d; sizeof(salt_value) = %d\n", strlen(salt_value), sizeof(salt_value)); 

    for(i = 0; i < KEY_LEN; i++) { 
     printf("%02x", salt_value[i]); 
    } 

    ret = PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), salt_value, strlen(salt_value), ITERATION, KEK_KEY_LEN, out); 
    printf("\n PKCS#5 :"); 

    for(len = 0; len < KEK_KEY_LEN; len++){ 
     printf("%02x", out[len]); 

     sprintf(&rspPKCS5[len * 2], "%02x", out[len]); 
    } 

    printf("\n"); 
} 

Esempio di output: risultato

salt_value[0] = e2; salt_value[31]= 12 
strlen(salt_value) = 32; sizeof(salt_value) = 32 
e258017933f3e629a4166cece78f3162a3b0b7edb2e94c93d76fe6c38198ea12 
PKCS#5 :7d7ec9f411 

Sito web:

The derived 40-bit key is: a5caf6a0d3 
+0

correlate, c'è ora una pagina di manuale per '' PKCS5_PBKDF2_HMAC' e PKCS5_PBKDF2_HMAC_SHA1'. Vedi ['PKCS5_PBKDF2_HMAC (3)'] (https://www.openssl.org/docs/crypto/PKCS5_PBKDF2_HMAC.html). – jww

risposta

15

In primo luogo, diamo un'occhiata a un official test vector per PBKDF2 HMAC-SHA1:

Input: 
    P = "password" (8 octets) 
    S = "salt" (4 octets) 
    c = 1 
    dkLen = 20 

Output: 
    DK = 0c 60 c8 0f 96 1f 0e 71 
     f3 a9 b5 24 af 60 12 06 
     2f e0 37 a6    (20 octets) 

Così ora sappiamo cosa stiamo girando sia sul web che nel tuo programma. Quindi, usando queste informazioni, scopriamo che il sito web vuole che il tuo sale sia una stringa ASCII, che poi convertirà in byte. Questo è importante perché non sarai mai in grado di abbinare l'output della pagina web se usi RAND_bytes per generare un salt.

password 
salt 
1 
20 
0c60c80f961f0e71f3a9b524af6012062fe037a6 

E si sta utilizzando il sale in modo errato. Nella tua riga commentata, stai generando una stringa con caratteri ASCII. Se vuoi usare quel sale, dovresti dichiararlo come una matrice di byte. Inoltre, ti manca una cifra.

unsigned char salt_value[]= { 0x5d, 0x85, 0x94, 0x7b, … /* and so on */ }; 

E nel codice non commentato, si sta generando un array di byte ma lo si considera come una stringa. Non si chiama strlen su una matrice di byte perché le matrici di byte possono contenere 0, che strlen interpreterà come terminatore nullo. In questo modo, puoi tenere traccia delle dimensioni manualmente (ad esempio, il tuo KEK_KEY_LEN definire per l'array si malloc) o utilizzare sizeof quando appropriato.

PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), salt_value, sizeof(salt_value), ITERATION, KEK_KEY_LEN, out); 

Quindi, ora che sappiamo che tutte queste cose, possiamo mettere insieme un programma completo che corrisponde l'uscita sia del sito web e il vettore di test ufficiale.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#include <openssl/evp.h> 

#define KEY_LEN  32 
#define KEK_KEY_LEN 20 
#define ITERATION  1 

int main() 
{ 
    size_t i; 
    unsigned char *out; 
    const char pwd[] = "password"; 
    unsigned char salt_value[] = {'s','a','l','t'}; 

    out = (unsigned char *) malloc(sizeof(unsigned char) * KEK_KEY_LEN); 

    printf("pass: %s\n", pwd); 
    printf("ITERATION: %u\n", ITERATION); 
    printf("salt: "); for(i=0;i<sizeof(salt_value);i++) { printf("%02x", salt_value[i]); } printf("\n"); 

    if(PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), salt_value, sizeof(salt_value), ITERATION, KEK_KEY_LEN, out) != 0) 
    { 
     printf("out: "); for(i=0;i<KEK_KEY_LEN;i++) { printf("%02x", out[i]); } printf("\n"); 
    } 
    else 
    { 
     fprintf(stderr, "PKCS5_PBKDF2_HMAC_SHA1 failed\n"); 
    } 

    free(out); 

    return 0; 
} 

(e notare che le esigenze principali per restituire un int e si dovrebbe liberare la memoria allocata)

gcc pkcs5.c -o pkcs5 -g -lcrypto -Wall 
./pkcs5 
pass: password 
ITERATION: 1 
salt: 73616c74 
out: 0c60c80f961f0e71f3a9b524af6012062fe037a6 
+0

Grazie indiv per la risposta. Quando faccio il sale usando RAND_bytes(), convertendolo in ASCII sono in grado di far corrispondere il risultato (come il mio programma lo fa), ma sto guardando usando i valori binari per PKCS5_PBKDF2_HMAC_SHA1(). È il loro modo per verificare se il risultato generato utilizzando corrispondenze binarie con l'output del programma? – pkumarn

+1

Il documento a cui mi sono collegato ha un vettore di prova che cattura gli errori in un'implementazione binaria utilizzando la password "pass \ 0word" e il sale "sa \ 0lt". '\ 0' rappresenta il byte 0x00.Se la tua implementazione può superare tutti i casi di test vettoriali di test, allora è considerata funzionalmente corretta. – indiv

+0

Grazie per la risposta, @indiv. La tua soluzione ha funzionato per me, ma ho dovuto usare strlen (salt_value) invece di sizeof (salt_value) nella chiamata a PKCS5_PBKDF2_HMAC_SHA1(). – MaxMarchuk