我尝试通过HMAC
实施sha256
,但我的输出与维基百科示例不同。
预期产出:
0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
实际输出:
0x18615993cb350238e00f3c9858befb04160c85b8b05d797486cc47d0d864c04b
代码:
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
unsigned char *hash(unsigned char *input, unsigned int in_len, unsigned int *out_len);
unsigned char *hmac(unsigned char *key, unsigned int key_len,
unsigned char *data, unsigned int data_len,
unsigned char *output, unsigned int *out_len);
void debug(unsigned char *in, unsigned int len);
int main(int argc, char **argv)
{
unsigned int asdf;
unsigned char *h = hmac("key", 3, "The quick brown fox jumps over the lazy dog",
strlen("The quick brown fox jumps over the lazy dog"),
NULL, NULL);
}
void debug(unsigned char *in, unsigned int len)
{
int i;
for(i=0;i<len;i++) {
printf("%02x", in[i]);
}
printf("\n");
}
unsigned char *hmac(unsigned char *key, unsigned int key_len,
unsigned char *data, unsigned int data_len,
unsigned char *output, unsigned int *out_len)
{
#define BLOCK_SIZE 32
int i, nkey, o_len;
char i_pad[BLOCK_SIZE], o_pad[BLOCK_SIZE];
/* Key init */
if(key_len > BLOCK_SIZE)
key = hash(key, key_len, &nkey);
else if(key_len < BLOCK_SIZE) {
// zero pad to the right
char *n_key = malloc(BLOCK_SIZE);
memset(n_key, '\0', BLOCK_SIZE);
memcpy(n_key, key, key_len);
key = n_key;
}
printf("key:\n");
debug(key, BLOCK_SIZE);
/* Padding init */
for(i=0;i<BLOCK_SIZE;i++) {
o_pad[i] = key[i] ^ 0x5c;
i_pad[i] = key[i] ^ 0x36;
}
printf("o_pad:\n");
debug(o_pad, BLOCK_SIZE);
printf("i_pad:\n");
debug(i_pad, BLOCK_SIZE);
/* Stage 1: calculate hash(i_pad . data)*/
unsigned char *stg1 = malloc(BLOCK_SIZE+data_len);
memcpy(stg1, i_pad, BLOCK_SIZE);
memcpy(stg1+BLOCK_SIZE, data, data_len);
printf("stg1 input:\n"); debug(stg1, BLOCK_SIZE+data_len);
stg1 = hash(stg1, BLOCK_SIZE+data_len, &o_len);
printf("stg1 hashed:\n"); debug(stg1, BLOCK_SIZE);
/* Stage 2: calculate hash(o_pad . stg1) */
unsigned char *stg2 = malloc(BLOCK_SIZE+o_len);
memcpy(stg2, o_pad, BLOCK_SIZE);
memcpy(stg2+BLOCK_SIZE, stg1, o_len);
printf("stg2 input:\n"); debug(stg2, BLOCK_SIZE+o_len);
stg2 = hash(stg2, BLOCK_SIZE*2+data_len, &o_len);
printf("stg2 hashed:\n"); debug(stg2, BLOCK_SIZE);
}
unsigned char *hash(unsigned char *input, unsigned int in_len, unsigned int *out_len)
{
EVP_MD_CTX ctx;
int i;
unsigned char *ret = malloc(EVP_MAX_MD_SIZE);
EVP_MD_CTX_init(&ctx);
EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(&ctx, input, in_len);
EVP_DigestFinal_ex(&ctx, ret, out_len);
EVP_MD_CTX_cleanup(&ctx);
return ret;
}
有人能发现任何明显的缺陷吗?感谢。
答案 0 :(得分:0)
你正在使用stg1做到这一点,但在最后阶段你应该使EVP_DigestUpdate两次而不是memcpy。
39c39
< #define BLOCK_SIZE 32
---
> #define BLOCK_SIZE 64
85,90d84
< memcpy(stg2, o_pad, BLOCK_SIZE);
< memcpy(stg2+BLOCK_SIZE, stg1, o_len);
<
< printf("stg2 input:\n"); debug(stg2, BLOCK_SIZE+o_len);
< stg2 = hash(stg2, BLOCK_SIZE*2+data_len, &o_len);
< printf("stg2 hashed:\n"); debug(stg2, BLOCK_SIZE);
91a86,96
> EVP_MD_CTX ctx;
> EVP_MD_CTX_init(&ctx);
> EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL);
> EVP_DigestUpdate(&ctx, o_pad, BLOCK_SIZE);
> EVP_DigestUpdate(&ctx, stg1, o_len);
> EVP_DigestFinal_ex(&ctx, stg2, &o_len);
> EVP_MD_CTX_cleanup(&ctx);
>
> printf("output:\n");
> debug(stg2, o_len);
> return stg2;
输出:
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8