Во-первых, давайте посмотрим на официальный тестовый вектор для 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)
Итак, теперь мы знаем, что мы снимаем как в Интернете, так и в вашемпрограмма.Таким образом, используя эту информацию, мы обнаруживаем, что веб-сайт хочет получить вашу соль в виде строки ASCII, которую он затем преобразует в байты.Это важно, потому что вы никогда не сможете соответствовать выводу веб-страницы, если вы используете RAND_bytes
для создания соли.
password
salt
1
20
0c60c80f961f0e71f3a9b524af6012062fe037a6
И вы используете соль неправильно.В вашей закомментированной строке вы генерируете строку с символами ASCII.Если вы хотите использовать эту соль, вам нужно объявить ее как массив байтов.Кроме того, вам не хватает цифры.
unsigned char salt_value[]= { 0x5d, 0x85, 0x94, 0x7b, … /* and so on */ };
И в некомментированном коде вы генерируете массив байтов, но обрабатываете его как строку.Вы не вызываете strlen
для массива байтов, потому что массивы байтов могут содержать 0, который strlen будет интерпретировать как нулевой терминатор.Таким образом, вы либо отслеживаете размер вручную (например, ваше определение KEK_KEY_LEN для массива, который вы используете malloc), либо вы используете sizeof
, когда это необходимо.
PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), salt_value, sizeof(salt_value), ITERATION, KEK_KEY_LEN, out);
Так что теперь, когда мы знаем все эти вещи, мы можем собрать их вместеполная программа, которая соответствует выводу как веб-сайта, так и официального вектора теста.
#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;
}
(и обратите внимание, что main должен вернуть int
, и вы должны освободить выделенную память)
gcc pkcs5.c -o pkcs5 -g -lcrypto -Wall
./pkcs5
pass: password
ITERATION: 1
salt: 73616c74
out: 0c60c80f961f0e71f3a9b524af6012062fe037a6