2012-03-19 2 views
10

J'essaie d'utiliser PKCS5_PBKDF2_HMAC_SHA1() et ci-dessous est mon exemple de programme. Je voulais m'assurer que mon résultat de PKCS5_PBKDF2_HMAC_SHA1() est correct, donc j'ai vérifié la même chose avec le site Web http://anandam.name/pbkdf2/ et je vois un résultat différent. Est-ce que j'utilise l'API correctement? J'ai des doutes si je passe correctement la valeur de sel.Comment utiliser PKCS5_PBKDF2_HMAC_SHA1()

J'ai collé mon résultat et le résultat du site après le programme.

S'il vous plaît aidez-moi à comprendre cela.

#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"); 
} 

Exemple de sortie:

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

Site résultat:

The derived 40-bit key is: a5caf6a0d3 
+0

connexes, il y a maintenant une page de manuel pour '' PKCS5_PBKDF2_HMAC' et PKCS5_PBKDF2_HMAC_SHA1'. Voir ['PKCS5_PBKDF2_HMAC (3)'] (https://www.openssl.org/docs/crypto/PKCS5_PBKDF2_HMAC.html). – jww

Répondre

15

D'abord, regardons un official test vector pour 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) 

Alors maintenant, nous savons ce que nous tournons à la fois sur le web et dans votre programme. Donc, en utilisant cette information, nous découvrons que le site Web veut que votre sel soit une chaîne ASCII, qu'il convertira ensuite en octets. Ceci est important car vous ne serez jamais capable de faire correspondre la sortie de la page Web si vous utilisez RAND_bytes pour générer du sel.

password 
salt 
1 
20 
0c60c80f961f0e71f3a9b524af6012062fe037a6 

Et vous utilisez incorrectement le sel. Dans votre ligne commentée, vous générez une chaîne avec des caractères ASCII. Si vous voulez utiliser ce sel, vous devez le déclarer comme un tableau d'octets. De plus, il vous manque un chiffre.

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

Et dans le code non mis en commentaire, vous générez un tableau d'octets mais en le traitant comme une chaîne. Vous n'appelez pas strlen sur un tableau d'octets car les tableaux d'octets peuvent contenir 0, que strlen interprétera comme un terminateur null. Vous devez donc suivre la taille manuellement (par exemple, votre KEK_KEY_LEN définir pour le tableau vous malloc) ou vous utilisez sizeof le cas échéant.

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

Maintenant que nous savons toutes ces choses, nous pouvons mettre en place un programme complet qui correspond à la sortie des deux le site Web et le vecteur de test officiel.

#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; 
} 

(et notez que les principaux besoins de retourner un int et vous devez libérer votre mémoire allouée)

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

Merci indiv pour la réponse. Quand je génère du sel en utilisant RAND_bytes(), le convertir en ASCII je suis capable de faire correspondre le résultat (comme mon programme le fait) mais je cherche à utiliser des valeurs binaires pour PKCS5_PBKDF2_HMAC_SHA1(). Est-ce leur moyen de vérifier si le résultat généré en utilisant des correspondances binaires avec la sortie du programme? – pkumarn

+1

Le document auquel je suis lié possède un vecteur de test qui détectera les erreurs dans une implémentation binaire en utilisant le mot de passe "pass \ 0word" et le sel "sa \ 0lt". Le '\ 0 'représente l'octet 0x00.Si votre implémentation réussit tous les tests élémentaires de test, elle est considérée comme fonctionnellement correcte. – indiv

+0

Merci pour la réponse, @indiv. Votre solution a fonctionné pour moi, mais j'ai dû utiliser strlen (salt_value) au lieu de sizeof (salt_value) dans l'appel à PKCS5_PBKDF2_HMAC_SHA1(). – MaxMarchuk