C HMAC实施输出检查

时间:2015-01-25 22:15:35

标签: c openssl hmac sha256

我尝试通过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;
}

有人能发现任何明显的缺陷吗?感谢。

1 个答案:

答案 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