我正在尝试下面的代码。问题是:有时候工作,有时候不工作!我正在使用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);
}
当我说它不起作用时,我的意思是,对于相同的数据和密钥,会返回不同的结果!
答案 0 :(得分:1)
不是将strlen(res_f);
作为输出缓冲区的长度返回,而是需要返回res_f_len
。
代码中strlen()
可能会发生三件事:
strlen
将返回比HMAC消息摘要短的长度。strlen
将读取消息摘要之外的内容,从而导致以下两种结果之一:
strlen
在消息摘要后读取内存中的垃圾,最终停止在随机0上。strlen
返回的值太大了。strlen
将返回消息摘要的实际长度。因此,只有在最后一个场景中,您才能获得正确的价值。这几乎是错误的。
似乎HMAC_Final
确实更新了传递给它的长度参数。 (See the example in the top-voted answer to this StackOverflow question。)这就是你传递指向int的原因。您应该只返回此更新值。