我已经读过,为了使用EVP_Digest调用发送要散列的大数据,可以多次调用EVP_DIgestUpdate。
我需要调用EVP_Update并获取部分计算的哈希值,然后发送剩余的输入(以及部分计算的哈希值)来计算输入的整个哈希值。
我已编写以下代码进行测试:
int try()
{
EVP_MD_CTX ctx;
const EVP_MD *md;
//char data[] = "Test Message\n";
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len, i;
char *data = "test";
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("SHA256");
if(!md) {
printf("Unknown message digest\n");
exit(1);
}
EVP_MD_CTX_init(&ctx);
EVP_DigestInit_ex(&ctx, md, NULL);
EVP_DigestUpdate(&ctx, data, strlen(data));
//EVP_DigestUpdate(&ctx, toB64val, strlen(toB64val));
EVP_DigestFinal_ex(&ctx, md_value, &md_len); //retrieve digest from ctx unto md_value and #bytes written is copied into md_len
EVP_MD_CTX newctx;
//char data[] = "Test Message\n";
unsigned char new_md_value[EVP_MAX_MD_SIZE];
unsigned int new_md_len;
EVP_MD_CTX_init(&newctx);
EVP_DigestInit_ex(&newctx, md, NULL);
char *newdata = " message";
printf("md_len = %d\n", md_len);
int newlen = md_len;
EVP_DigestUpdate(&newctx, md_value, 32);
EVP_DigestUpdate(&newctx, newdata, strlen(data));
//EVP_DigestUpdate(&ctx, toB64val, strlen(toB64val));
EVP_DigestFinal_ex(&newctx, new_md_value, &new_md_len);
EVP_MD_CTX_cleanup(&newctx);
printf("Digest is: ");
for(i = 0; i < new_md_len; i++) printf("%02x", new_md_value[i]);
printf("\n");
return 0;
}
我正在尝试为&#34;测试消息&#34;计算哈希值(sha256)。作为我的输入。 但是,我需要能够检索&#34;部分计算的哈希&#34;的&#34;测试&#34;然后再将它再次提供给另一个新的上下文计算整个输入。
然而哈希o&#34;测试消息&#34;如单独计算不匹配。有人可以帮忙吗?
谢谢
答案 0 :(得分:0)
SHA256块大小为64字节,因此您只能在输入消息的64字节边界上获得有意义的部分哈希。在内部,EVP正在缓冲消息,直到它达到64字节。
当请求散列结果时,消息用1位填充,后跟0位,后跟64位消息长度(以位为单位),使其成为64字节的倍数。
因此,您计算的第一个哈希是在消息上:
c = '\0';
其次,即使您的部分消息是64字节的倍数,您也不能将部分散列作为数据传递给新散列。假设您打算在最后一次调用{"test", 1'b1, 415'b0, 64'h32}
时传递strlen(newdata)
而不是strlen(data)
,那么您计算的哈希值将超过填充的320位消息:
EVP_DigestUpdate
与填充的96位消息的哈希值不同:
{<32-byte hash>, " message", 1'b1, 127'b0, 64'h320}
为了继续部分哈希,必须保存并恢复哈希状态({"test message", 1'b1, 351'b0, 64'h96}
)(不确定EVP是否为此提供API)。因为您的部分消息太短,所以哈希状态将不会从初始更新,并且消息残留(最后未完成块的部分)将位于EVP上下文内的缓冲区中,等待用于构成块的更多数据。因此,除了哈希状态之外,您还需要保存并恢复消息残留。
答案 1 :(得分:0)
如果要获取“部分摘要”,可以复制EVP_MD_CTX
,然后从副本中获取摘要。因此:
EVP_MD_CTX ctx, partial_ctx;
/* ... call EVP_DigestUpdate() several times... */
EVP_DigestUpdate(&ctx, data, data_len);
/* Now, we're going to get the digest up thus far, without
* interrupting/changing the final digest, by making a copy of ctx,
* and using the copy to get the partial digest.
*/
EVP_MD_CTX_init(&partial_ctx);
EVP_MD_CTX_copy(&partial_ctx, &ctx);
EVP_DigestFinal_ex(&partial_ctx, partial_md_value, &partial_md_len);
/* Don't forget to cleanup the partial ctx. */
EVP_MD_CTX_cleanup(&partial_ctx);
/* Continue digesting more data to get the final digest. */
EVP_DigestUpdate(&ctx, data, data_len);
希望这有帮助!