OpenSSL之消息认证码HMAC用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenSSL之消息认证码HMAC用法相关的知识,希望对你有一定的参考价值。

参考技术A HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,由H.Krawezyk,M.Bellare,R.Canetti于1996年提出的一种基于Hash函数和密钥进行消息认证的方法,并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。

本文假设你已经安装好了OpenSSL,并且持有一份1.1.1的源码。
HMAC相关的头文件在hmac.h中、源文件在crypto/hmac目录中。

这个结构定义了HMAC的运算上下文。主要字段含义:
md —— 摘要算法。
md_ctx —— 摘要算法上下文。
i_ctx —— 这两个结构参与密码填充散列运算。
o_ctx —— 这两个结构参与密码填充散列运算。

其中,EVP_MD的定义为:

这个结束定义了进行通用摘要运算的抽象方法集合。

在1.1.1中,大多数的数据结构已经不再向使用者开放,从封装的角度来看,这是更合理的。如果你在头文件中找不到结构定义,不妨去源码中搜一搜。

HMAC_CTX *HMAC_CTX_new(void);
创建HMAC上下文结构。
void HMAC_CTX_free(HMAC_CTX *ctx);
释放HMAC上下文结构。

int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md);
初使化HMAC上下文结构,key和len指定密码。
成功返回1,失败返回0。

int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
向HMAC上下文输入字节流。
成功返回1,失败返回0。

int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
生成最终的HMAC串。
成功返回1,失败返回0。
成功时len更新为HMAC的长度。

unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
const unsigned char *d, size_t n, unsigned char *md,
unsigned int *md_len);
对于短的字符串,可以使用该函数一次性生成HMAC摘要,简化调用。

在evp.h中,有EVP_MD方法的相关定义:
const EVP_MD *EVP_md5(void);
const EVP_MD *EVP_sha1(void);
const EVP_MD *EVP_sha256(void);
const EVP_MD *EVP_sha512(void);

这个例子演示了使用两种方式生成消息认证码,并对比结果。

输出:
ret:1 outlen:20
962efe82ba78795e3bbf046c9af2370524f02215
ret 0x7ffc125eb730
sSHA 0x7ffc125eb730 nSHALen:20
962efe82ba78795e3bbf046c9af2370524f02215

关于消息认证码

我的认识

  • 消息认证码
    英文为Message Authentication Code,也称消息识别码等不同称呼。其主要功能是验证消息的真实性。
    消息认证模型如下:
    技术图片

  • HMAC(Hash-based Message Authentication Code)
    HMAC是一种使用单向散列函数构建MAC的方法,其中H就是Hash的意思。
    HMAC中所使用的单向散列函数并不仅限于一种,任何高强度的单向散列函数都可以被用于HMAC,如果将来设计出的新的单向散列函数,也同样可以使用。
    使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。
    各消息摘要长度不同,

  • 输入文本和密钥,输出固定长度的消息摘要。这段消息摘要是途中的认证码。

HMAC算法是一种基于密钥的报文完整性的验证方法 ,其安全性是建立在Hash加密算法基础上的。它要求通信双方共享密钥、约定算法、对报文进行Hash运算,形成固定长度的认证码。通信双方通过认证码的校验来确定报文的合法性。 HMAC算法可以用来作加密、数字签名、报文验证等 。

HMAC的算法定义

HMAC算法是一种执行“校验和”的算法,它通过对数据进行“校验”来检查数据是否被更改了。在发送数据以前,HMAC算法对数据块和双方约定的公钥进行“散列操作”,以生成称为“摘要”的东西,附加在待发送的数据块中。当数据和摘要到达其目的地时,就使用HMAC算法来生成另一个校验和,如果两个数字相匹配,那么数据未被做任何篡改。否则,就意味着数据在传输或存储过程中被某些居心叵测的人作了手脚。

HMAC算法的定义用公式表示如下:

HMAC(K,M)=H((K’⊕opad)∣H((K’⊕ipad)∣M))

算法步骤

(1) 在密钥K后面添加0 或者 对密钥K用H进行处理 来创建一个字长为B的字符串。(例如,如果K的字长是20字节,B=64字节,则K后会加入44个零字节0x00;如果K的字长是120字节,B=64字节,则会用H作用于K后产生64字节的字符串)

(2) 将上一步生成的B字长的字符串与ipad做异或运算。

(3) 将数据流text填充至第二步的结果字符串中。

(4) 用H作用于第三步生成的数据流。

(5) 将第一步生成的B字长字符串与opad做异或运算。

(6) 再将第四步的结果填充进第五步的结果中。

(7) 用H作用于第六步生成的数据流,输出最终结果 。

以上是关于OpenSSL之消息认证码HMAC用法的主要内容,如果未能解决你的问题,请参考以下文章

关于消息认证码

nodeJS之crypto模块md5和Hmac加密

信息摘要算法之五:HMAC算法分析与实现

HMAC-SHA1签名认证算法

Go-哈希函数与消息认证详解(含代码)

Java加密算法---HMAC