【问题标题】:Using HMAC vs EVP functions in OpenSSL在 OpenSSL 中使用 HMAC 与 EVP 函数
【发布时间】:2015-06-12 16:20:01
【问题描述】:

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

【问题讨论】:

    标签: c openssl hmac


    【解决方案1】:

    ... EVP和HMAC有什么区别

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

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

    这是一个基于 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 与哈希略有不同。 HMAC 是键控散列,而散列没有键控。您还可以使用 EVP_* 函数进行 HMAC'ing。以下来自 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");
    

    【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-10-03
      • 2015-09-07
      • 2016-02-07
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 2020-12-20
      • 2017-05-29
      • 1970-01-01
      相关资源
      最近更新 更多