如何使用 PKCS5_PBKDF2_HMAC_SHA1() [英] How to use PKCS5_PBKDF2_HMAC_SHA1()

查看:47
本文介绍了如何使用 PKCS5_PBKDF2_HMAC_SHA1()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 PKCS5_PBKDF2_HMAC_SHA1(),下面是我的示例程序.我想确定我的 PKCS5_PBKDF2_HMAC_SHA1() 的结果是否正确,所以我在网站 http://anandam.name/pbkdf2/ 我看到了不同的结果.我是否正确使用了 API?

I am trying to use PKCS5_PBKDF2_HMAC_SHA1() and below is my sample program. I wanted to make sure if my result of PKCS5_PBKDF2_HMAC_SHA1() is correct so I verified the same with the website http://anandam.name/pbkdf2/ and I see a different result. Am I using the API correctly?

我怀疑我是否正确传递了盐值.

I am having doubts if I am passing salt value correctly.

我在程序后粘贴了我的结果和网站结果.

I have pasted my result and website result after the program.

请帮助我理解这一点.

#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("
 salt_value[0] = %x; salt_value[31]= %x", salt_value[0], salt_value[31]); 
    printf("
 strlen(salt_value) = %d; sizeof(salt_value) = %d
", 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("
 PKCS#5 :"); 

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

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

    printf("
"); 
} 

样本输出:

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

网站结果:

The derived 40-bit key is: a5caf6a0d3 

推荐答案

首先,我们来看一个 官方测试向量 PBKDF2 HMAC-SHA1:

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)

现在我们知道我们要在网络上和您的节目中拍摄什么内容了.因此,使用该信息,我们发现该网站希望将您的盐作为 ASCII 字符串,然后将其转换为字节.这很重要,因为如果您使用 RAND_bytes 生成盐,您将永远无法匹配网页的输出.

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

而且您使用的盐不正确.在您的注释行中,您正在生成一个带有 ASCII 字符的字符串.如果要使用该盐,则必须将其声明为字节数组.另外,您还缺少一个数字.

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 */ };

在未注释的代码中,您生成了一个字节数组,但将其视为字符串.您不会对字节数组调用 strlen,因为字节数组可以包含 0,而 strlen 会将其解释为空终止符.因此,您要么手动跟踪大小(例如,您的 KEK_KEY_LEN 为您分配的数组定义),要么在适当的时候使用 sizeof.

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
", pwd);
    printf("ITERATION: %u
", ITERATION);
    printf("salt: "); for(i=0;i<sizeof(salt_value);i++) { printf("%02x", salt_value[i]); } printf("
");

    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("
");
    }
    else
    {
        fprintf(stderr, "PKCS5_PBKDF2_HMAC_SHA1 failed
");
    }
 
    free(out);

    return 0;
}

(注意 main 需要返回一个 int 并且你应该释放你分配的内存)

(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

这篇关于如何使用 PKCS5_PBKDF2_HMAC_SHA1()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆