pku*_*arn 12 openssl salt pbkdf2
我正在尝试使用PKCS5_PBKDF2_HMAC_SHA1(),以下是我的示例程序.我想确定我的结果PKCS5_PBKDF2_HMAC_SHA1()是否正确所以我通过网站http://anandam.name/pbkdf2/验证了相同的结果,我看到了不同的结果.我正确使用API吗?
如果我正确地传递盐值,我有疑问.
我在程序后粘贴了我的结果和网站结果.
请帮我理解这个.
#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");
}
Run Code Online (Sandbox Code Playgroud)
样本输出:
salt_value[0] = e2; salt_value[31]= 12
strlen(salt_value) = 32; sizeof(salt_value) = 32
e258017933f3e629a4166cece78f3162a3b0b7edb2e94c93d76fe6c38198ea12
PKCS#5 :7d7ec9f411
Run Code Online (Sandbox Code Playgroud)
网站结果:
The derived 40-bit key is: a5caf6a0d3
Run Code Online (Sandbox Code Playgroud)
ind*_*div 18
首先,让我们看一下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)
Run Code Online (Sandbox Code Playgroud)
所以现在我们知道我们在网络和你的程序中拍摄的内容.因此,使用该信息,我们发现该网站希望您的salt作为ASCII字符串,然后将其转换为字节.这很重要,因为如果您使用RAND_bytes生成盐,则永远无法匹配网页的输出.
password
salt
1
20
0c60c80f961f0e71f3a9b524af6012062fe037a6
Run Code Online (Sandbox Code Playgroud)
你错了使用盐.在注释行中,您将生成一个包含ASCII字符的字符串.如果要使用该盐,则必须将其声明为字节数组.另外,你错过了一个数字.
unsigned char salt_value[]= { 0x5d, 0x85, 0x94, 0x7b, … /* and so on */ };
Run Code Online (Sandbox Code Playgroud)
在未注释的代码中,您生成一个字节数组,但将其视为字符串.您不调用strlen字节数组,因为字节数组可以包含0,strlen将其解释为空终止符.因此,您可以手动跟踪大小(例如,您对malloc阵列的KEK_KEY_LEN定义),也可以sizeof在适当时使用.
PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), salt_value, sizeof(salt_value), ITERATION, KEK_KEY_LEN, out);
Run Code Online (Sandbox Code Playgroud)
所以现在我们知道所有这些事情,我们可以整合一个完整的程序,匹配网站和官方测试向量的输出.
#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;
}
Run Code Online (Sandbox Code Playgroud)
(并注意主要需要返回一个int,你应该释放你分配的内存)
gcc pkcs5.c -o pkcs5 -g -lcrypto -Wall
./pkcs5
pass: password
ITERATION: 1
salt: 73616c74
out: 0c60c80f961f0e71f3a9b524af6012062fe037a6
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18922 次 |
| 最近记录: |