消息认证码是做什么用的呢? 在上一篇散列函数中,我们提到过通过散列函数我们确保消息原文并没有被篡改过。但无法保证消息是双方真实意思的表现。
比如说 Bob 收到一条借款消息,上面写着请 Bob 给 Alice 的银行账户 xxxxx 转 1000. Bob 通过计算消息内容的散列函数,证实消息没有被篡改过。 那么此时此刻,Bob 应该给这个账户转账吗?
必须不能!
因为 Bob 并不能证实这条消息是来自于 Alice 的。 有可能这条消息来自于 Eve。 所有仅通过散列函数只能解决是否篡改,而不能解决是否真实。
这是 Bob 以为的
而实际上却是这样的:
而消息认证码则可以解决这个问题。
消息认证码是一种确认信息完整性并可以进行认证的技术,简称 MAC(Message Authentication Code)。
MAC 由两部分组成: 消息 + 共享密钥。
和散列函数类似, MAC 可以将任意长度的消息计算出固定长度的输出值。但和散列函数不同的是,如果没有共享密钥,则无法计算出最终的 MAC 值。 所以通过这一个性质来确保安全性。
简单来说:
MAC = 单向散列 + 共享密钥
仍然以 Bob 和 Alice 之间借钱的例子开始说。 假设这俩人之间通过 MAC 确保安全性,那么双方处理流程应该大致是这个样子:
我们做个步骤分解:
在 MAC 算法里面既然提到了共享密钥,那么就无法逃离对称密钥体系的宿命:"密钥配送问题"。 而解决这个问题,目前来说只能依靠公钥密钥、Diffie-Hellman 密钥交换,密钥中心等解决方案。
可能还有同学存在疑问,既然 mac 算法中已经存在共享密钥这个元素了,那么直接用共享密钥计算密文不就好了么?
Bob 能解开就说明合法,如果解不开就说明非法。这样简单明了多好。
应该说这种想法是一半对一半错。 对的是,如果解开了能说明合法,解不开是非法。 但错误的是如果解开了是乱码,那么是合法还是非法?
这是因为仅凭是否可以解开密文,并不能完整地表示出对方的意图。 如果我们做业务开发,双方约定好了报文。那么针对解开的数据进行报文解析,在解密成功但解析失败时,我们可以认为是非法请求。
但如果我们做系统级通用模块时,我们无法得知对方可能传输哪些数据时,仅仅单凭是否可以解开数据来判断合法和非法,这就有些武断了。
所以需要确保消息一定是对方传输的场合中,都会采用 MAC 的方法来校验合法性和完整性。 常用的 MAC 算法则是 HMAC。
HMAC 的 H 指的是 Hash 的意思,是一种利用 Hash 来构造消息认证码的算法。 我们说过MAC = 散列函数 + 共享密钥 。 HMAC 使用的散列函数有:SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 几种函数。 因此相对应的 HMAC 也称为:HMAC-SHA-1、HMAC-SHA-224、HMAC-SHA-256、HMAC-SHA-384、HMAC-SHA-512.
HMAC 用数学公式来表示是:
hash(opadKey || hash(ipadKey || message ))
其中:
ipadKey 是 key(密钥) ⊕ ipad(内部 16 进制的 36 比特流) opadKey 是 key(密钥) ⊕ opad(外部 16 进制的 5C 比特流)
所以 HMAC 是两层 HASH 的结果值。
用流程图表示则如下图所示:
同样步骤分解:
如果密钥不足预设长度(散列函数的分组长度),则填充'0'。如果长呢?那就用散列函数计算固定长度的散列值作为密钥值
使用 HMAC 可以解决消息合法性和完整性的问题,但却无法抵御重放攻击。 比如 Eve 截获到 Alice 和 Bob 之间的 Hmac 报文后,无限制的重复这段报文。 那么 Bob 就会无限制的进行转账。所以使用 HMAC 进行消息认证时,也会配合序号、时间戳等辅助信息,来判断报文是否需要处理。
同时 HMAC 也无法解决否认的问题,比如 Alice 完全可以事后否认找 Bob 借过钱,因为 Bob 完全有能力伪造出这段报文。即便 Bob 拿出了 MAC 值,也无法证明是 Alice 生成的。
那又该如何证明钱是由 Alice 借的呢?
这就需要数字签名技术了
留言与评论(共有 0 条评论) “” |