OpenSSL DigestInit_ex

OpenSSL DigestInit_ex

我正在使用 OpenSSL 解密传入的数据包,我正在使用 EVP 库来完成这项工作,我首先解密数据包,然后计算 hmac。

EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_DecryptUpdate(ctx, payload, &len, payload, data_len);
EVP_DecryptFinal_ex(ctx, payload + len, &len);

和 HMAC

EVP_PKEY *skey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, hmac_key, 32);
EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
EVP_DigestSignInit(md_ctx, NULL, md, NULL, skey);
EVP_DigestSignUpdate(md_ctx, hmac_payload, m+13);
EVP_DigestSignFinal(md_ctx, buff, &size);

现在,这工作得很好,但问题是每次我解密和计算 HMAC 之前都必须调用 init 函数,这效率不高,因为每个数据包都有相同的解密和 HMAC 密钥。

是否可以不用每次都调用初始化函数,用相同的密钥对每个数据包进行解密和hmac计算?显然,如果我从我的代码中删除它们,解密和 HMAC 计算将无法正常工作。

不,OpenSSL 实现不可能。

在 OpenSSL 术语中,像 EVP_CIPHER_CTXEVP_MD_CTX 这样的 "context" 是 one 所需的所有状态的容器encryption/decryption操作,或一个摘要。要为下一个 encryption/decryption 或摘要重置上下文(从而清除所有先前的状态),需要调用 EVP_DigestInit_ex()EVP_DecryptInit_ex()

另一种看待这个问题的方法是,您(程序员)可以在每个 EVP_DigestInit_ex() 上更改 cipher/digest 算法或其他参数或 EVP_DecryptInit_ex() 呼叫;底层上下文不知道你的意图。因此,每次调用初始化函数以重新使用该上下文结构时,都会为 这些 初始化参数(下次可能不同)准备该结构。

希望对您有所帮助!