初学者的C ++内存分配一塌糊涂

时间:2013-12-19 00:24:51

标签: c++ memory-management openssl hmac

我正在尝试下面的代码。问题是:有时候工作,有时候不工作!我正在使用OpenSSL库,但我相信我的错误很简单,C相关。

int test_c(string to_sign, string key)
{
    const void* key_void = (const void*)key.c_str();
    int key_size = key.size();

    const unsigned char* data_char = (const unsigned char*)to_sign.c_str();
    int data_size = to_sign.size();

    unsigned int res_f_len = data_size*8;
    unsigned char* res_f = (unsigned char*) malloc(sizeof(unsigned char)*res_f_len);

    HMAC_CTX ctx;
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key_void, key_size, EVP_sha256(), NULL);
    HMAC_Update(&ctx, data_char, data_size);
    HMAC_Final(&ctx, res_f, &res_f_len);
    HMAC_CTX_cleanup(&ctx);

    return strlen(res_f);
}

当我说它不起作用时,我的意思是,对于相同的数据和密钥,会返回不同的结果!

1 个答案:

答案 0 :(得分:1)

不是将strlen(res_f);作为输出缓冲区的长度返回,而是需要返回res_f_len

代码中strlen()可能会发生三件事:

  • 如果HMAC消息摘要的字节等于零,strlen将返回比HMAC消息摘要短的长度。
  • 如果HMAC消息摘要没有零字节,则strlen将读取消息摘要之外的内容,从而导致以下两种结果之一:
    • strlen在消息摘要后读取内存中的垃圾,最终停止在随机0上。strlen返回的值太大了。
    • 如果您非常幸运,消息摘要后的第一个字节为0,在这种情况下strlen将返回消息摘要的实际长度。

因此,只有在最后一个场景中,您才能获得正确的价值。这几乎是错误的。

似乎HMAC_Final确实更新了传递给它的长度参数。 (See the example in the top-voted answer to this StackOverflow question。)这就是你传递指向int的原因。您应该只返回此更新值。