Ответ 1
Во-первых, рассмотрим официальный тестовый вектор для 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