在OpenSSL中使用HMAC与EVP功能

时间:2012-09-22 16:50:32

标签: c openssl hmac

这是一个非常基本的问题,但EVP和HMAC之间有什么区别? EVP是一个消息摘要,但它与HMAC生成的内容有何不同?

2 个答案:

答案 0 :(得分:5)

  

...... EVP和HMAC之间有什么区别

EVP_*函数是一个高级接口。 HMAC_*AES_*和朋友是较低级别的原语。您可以使用其中任何一个,但建议您使用EVP_*函数。 HMAC_*例程是基于软件的,不使用硬件。

EVP_*函数将允许您轻松交换不同的哈希值,代码基本上保持不变。您将利用硬件加速,例如AES-NI用于AES-CMAC(如果可用)。

这是一个基于https://www.openssl.org/docs/crypto/EVP_DigestInit.html的OpenSSL示例。

EVP_MD_CTX* mdctx = NULL;
const EVP_MD* md = NULL;

unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len = 0;

char message[] = "Now is the time for all good men to "
    "come to the aide of their country\n";

OpenSSL_add_all_digests();

md = EVP_get_digestbyname("SHA1");
mdctx = EVP_MD_CTX_create();

if(!EVP_DigestInit_ex(mdctx, md, NULL))
    handleError();

if(!EVP_DigestUpdate(mdctx, message, strlen(message)))
    handleError();

if(!EVP_DigestFinal_ex(mdctx, md_value, &md_len))
    handleError();

if(!EVP_MD_CTX_destroy(mdctx))
    handleError();

printf("Digest is: ");
for(int i = 0; i < md_len; i++)
    printf("%02x", md_value[i]);
printf("\n");

现在,HMAC与Hash略有不同。 HMAC是键控散列,而散列不是键控的。您还可以使用EVP_*函数进行HMAC。以下是来自OpenSSL的wiki页面EVP Signing and Verifying

EVP_MD_CTX* mdctx = NULL;
const EVP_MD* md = NULL;
EVP_PKEY *pkey = NULL;

unsigned char md_value[EVP_MAX_MD_SIZE];   
int md_len = 0;

char message[] = "Now is the time for all good men to "
    "come to the aide of their country\n";

OpenSSL_add_all_digests();

if(!(mdctx = EVP_MD_CTX_create()))
    handleError();

if(!(md = EVP_get_digestbyname("SHA1")))
    handleError();

if(!(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, "password", strlen("password"))))
    handleError();

if(1 != EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey))
    handleError();

/* Call update with the message */
if(1 != EVP_DigestSignUpdate(mdctx, message, strlen(message)))
    handleError();

if(1 != EVP_DigestSignFinal(mdctx, md_value, &md_len))
    handleError();

printf("HMAC is: ");
for(int i = 0; i < md_len; i++)
    printf("%02x", md_value[i]);
printf("\n");

低级别界面看起来类似于:

EVP_MD_CTX* mdctx = NULL;
const EVP_MD* md = NULL;

unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len = 0;

char message[] = "Now is the time for all good men to "
"come to the aide of their country\n";

OpenSSL_add_all_digests();

md = EVP_get_digestbyname("SHA1");
mdctx = EVP_MD_CTX_create();

if(!HMAC_Init_ex(mdctx, key, sizeof(key), md, NULL))
    handleError();

if(!HMAC_Update(mdctx, message, strlen(message)))
    handleError();

if(!HMAC_Final(mdctx, md_value, &md_len))
    handleError();

if(!HMAC_CTX_cleanup(mdctx))
    handleError();

printf("HMAC is: ");
for(int i = 0; i < md_len; i++)
    printf("%02x", md_value[i]);
printf("\n");

答案 1 :(得分:1)

您需要使用EVP_PKEY_new_mac_key函数才能获得HMAC的正确密钥结构。并且不要忘记使用EVP_PKEY_free释放它。