How to use PKCS5_PBKDF2_HMAC_SHA1()

天大地大妈咪最大 提交于 2019-11-28 05:32:35
indiv

First, let's look at an official test vector for 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)

So now we know what we're shooting for both on the web and in your program. So using that info, we find out that the web site wants your salt as an ASCII string, which it will then convert to bytes. This is important because you'll never be able to match the web page's output if you use RAND_bytes to generate a salt.

password
salt
1
20
0c60c80f961f0e71f3a9b524af6012062fe037a6

And you are using the salt incorrectly. In your commented line, you're generating a string with ASCII characters. If you want to use that salt, you'd have to declare it as an array of bytes. Plus, you're missing a digit.

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

And in the uncommented code, you're generating an array of bytes but treating it as a string. You don't call strlen on an array of bytes because arrays of bytes can contain 0, which strlen will interpret as a null terminator. So you either track the size manually (e.g., your KEK_KEY_LEN define for the array you malloc) or you use sizeof when appropriate.

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

So now that we know all these things, we can put together a full program that matches the output of both the web site and the official test vector.

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

(and note that main needs to return an int and you should free your allocated memory)

gcc pkcs5.c -o pkcs5 -g -lcrypto -Wall
./pkcs5
pass: password
ITERATION: 1
salt: 73616c74
out: 0c60c80f961f0e71f3a9b524af6012062fe037a6
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!