密码体系六 - 消息认证码

消息认证码是做什么用的呢? 在上一篇散列函数中,我们提到过通过散列函数我们确保消息原文并没有被篡改过。但无法保证消息是双方真实意思的表现。

比如说 Bob 收到一条借款消息,上面写着请 Bob 给 Alice 的银行账户 xxxxx 转 1000. Bob 通过计算消息内容的散列函数,证实消息没有被篡改过。 那么此时此刻,Bob 应该给这个账户转账吗?

必须不能!

因为 Bob 并不能证实这条消息是来自于 Alice 的。 有可能这条消息来自于 Eve。 所有仅通过散列函数只能解决是否篡改,而不能解决是否真实。

这是 Bob 以为的

而实际上却是这样的:

而消息认证码则可以解决这个问题。

何为消息认证码

消息认证码是一种确认信息完整性并可以进行认证的技术,简称 MAC(Message Authentication Code)。

MAC 由两部分组成: 消息 + 共享密钥。

和散列函数类似, MAC 可以将任意长度的消息计算出固定长度的输出值。但和散列函数不同的是,如果没有共享密钥,则无法计算出最终的 MAC 值。 所以通过这一个性质来确保安全性。

简单来说:

MAC = 单向散列 + 共享密钥

如何使用 MAC

仍然以 Bob 和 Alice 之间借钱的例子开始说。 假设这俩人之间通过 MAC 确保安全性,那么双方处理流程应该大致是这个样子:

我们做个步骤分解:

  1. Alice 将借钱消息发给 Bob。
  2. Bob 收到借钱消息后并不急于执行,而是等着 Alice 发来消息认证码
  3. Alice 通过共享密钥和散列函数计算出 mac
  4. Alice 将消息认证码发送给 Bob
  5. Bob 按照相同的规则计算一遍 Mac
  6. Bob 将自己计算的 Mac 和 Alice 发来的 Mac 比对一遍。通过是否相同判断请求是否合法

MAC 的问题

在 MAC 算法里面既然提到了共享密钥,那么就无法逃离对称密钥体系的宿命:"密钥配送问题"。 而解决这个问题,目前来说只能依靠公钥密钥、Diffie-Hellman 密钥交换,密钥中心等解决方案。

可能还有同学存在疑问,既然 mac 算法中已经存在共享密钥这个元素了,那么直接用共享密钥计算密文不就好了么?

Bob 能解开就说明合法,如果解不开就说明非法。这样简单明了多好。

应该说这种想法是一半对一半错。 对的是,如果解开了能说明合法,解不开是非法。 但错误的是如果解开了是乱码,那么是合法还是非法?

这是因为仅凭是否可以解开密文,并不能完整地表示出对方的意图。 如果我们做业务开发,双方约定好了报文。那么针对解开的数据进行报文解析,在解密成功但解析失败时,我们可以认为是非法请求。

但如果我们做系统级通用模块时,我们无法得知对方可能传输哪些数据时,仅仅单凭是否可以解开数据来判断合法和非法,这就有些武断了。

所以需要确保消息一定是对方传输的场合中,都会采用 MAC 的方法来校验合法性和完整性。 常用的 MAC 算法则是 HMAC。

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'。如果长呢?那就用散列函数计算固定长度的散列值作为密钥值

  1. 将填充后的密钥与 Ipad 进行异或操作,最后达到散列函数分组长度。此时将此值称为IpadKey
  2. IpadKey附加在 message 开头
  3. 将第三步的结果输入 hash 函数,得出散列值
  4. 将填充后的密钥与 Opad 进行异或操作,最后达到散列函数分组长度。此时将此值称为OpadKey
  5. IpadKey附加在 message 末尾
  6. 将第六步的结果输入 hash 函数,得出散列值

总结

使用 HMAC 可以解决消息合法性和完整性的问题,但却无法抵御重放攻击。 比如 Eve 截获到 Alice 和 Bob 之间的 Hmac 报文后,无限制的重复这段报文。 那么 Bob 就会无限制的进行转账。所以使用 HMAC 进行消息认证时,也会配合序号、时间戳等辅助信息,来判断报文是否需要处理。

同时 HMAC 也无法解决否认的问题,比如 Alice 完全可以事后否认找 Bob 借过钱,因为 Bob 完全有能力伪造出这段报文。即便 Bob 拿出了 MAC 值,也无法证明是 Alice 生成的。

那又该如何证明钱是由 Alice 借的呢?

这就需要数字签名技术了

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章