密码学学习记录|hash hmac 算法

密码学学习记录 10 / 18

维基百科

密钥散列消息认证码(英语:Keyed-hash message authentication code),又称散列消息认证码(Hash-based message authentication code,缩写为HMAC),是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个加密密钥。它可以用来保证资料的完整性,同时可以用来作某个消息的身份验证。

参考资料

  • 1、rfc2104
  • 2、hmac wikipedia
  • 3、部分文案来自网上文章

MAC

在现代的网络中,身份认证是一个经常会用到的功能,在身份认证过程中,有很多种方式可以保证用户信息的安全,而MAC(message authentication code)就是一种常用的方法。

消息认证码是对消息进行认证并确认其完整性的技术。通过使用发送者和接收者之间共享的密钥,就可以识别出是否存在伪装和篡改行为。

MAC是通过MAC算法+密钥+要加密的信息一起计算得出的。

同hash算法(消息摘要)相比,消息摘要只能保证消息的完整性,即该消息摘要B是这个消息A生成的。而MAC算法能够保证消息的正确性,即判断确实发的是消息A而不是消息C。

同公私钥体系相比,因为MAC的密钥在发送方和接收方是一样的,所以发送方和接收方都可以来生成MAC,而公私钥体系因为将公钥和私钥分开,所以增加了不可抵赖性。

MAC有很多实现方式,比较通用的是基于hash算法的MAC,比如今天我们要讲的HMAC。还有一种是基于分组密码的实现,比如(OMAC, CBC-MAC and PMAC)。

HMAC 定义

hmac 数学公式(维基百科)

  • H为密码散列函数(如SHA家族)

  • K为密钥(secret key)

  • m是要认证的消息

  • K'是从原始密钥K导出的另一个秘密密钥(如果K短于散列函数的输入块大小,则向右填充(Padding)
    零;如果比该块大小更长,则对K进行散列)

  • || 代表串接

  • ⊕ 代表异或(XOR)

  • opad 是外部填充(0x5c5c5c…5c5c,一段十六进制常量)

  • ipad 是内部填充(0x363636…3636,一段十六进制常量)

Python 实现 HMAC 算法(拿 MD5 算法举例)

既然要拿 md5 算法举例,就先实现标准的算法流程,update transform 函数也是必不可少

hmac 实现,可以参考 python 里的 hmac 模块

  • 总结 hmac 加密流程,就是以下代码
msg = 'hello'.encode()
key = 'hello'.encode().ljust(64, b'\0')
key_5C = bytes.fromhex(''.join([hex(i ^ 0x5C).replace('0x', '').rjust(2, '0') for i in key]))
key_36 = bytes.fromhex(''.join([hex(i ^ 0x36).replace('0x', '').rjust(2, '0') for i in key]))

print(HashMD5().update(key_5C + HashMD5(key_36 + msg).digest()).hexdigest())

跟标准的运行结果对比一下,都是相同的,包括我们自定义的 HashMD5 也是可以当作参数传递进去

为了 Hmac 实现的更优雅,博主也是参考了 hmac 模块,重写了个 class,以下是代码

代码还不是很完善,是针对 md5 写的,下面来看下结果

def main():
    key = 'hello'.encode()
    msg = 'hello'.encode()

    hh1 = hmac.new(key, msg, 'md5')
    hh1.update(msg)
    hh1.update(msg)
    print(hh1.hexdigest())
    hh1.update(msg)
    hh1.update(msg)
    print(hh1.hexdigest())

    print('')

    hh2 = hmac.new(key, msg, HashMD5)
    hh2.update(msg)
    hh2.update(msg)
    print(hh2.hexdigest())
    hh2.update(msg)
    hh2.update(msg)
    print(hh2.hexdigest())

    print('')

    hh3 = HashHmac(key, msg, HashMD5)
    hh3.update('hello')
    hh3.update('hello')
    print(hh3.hexdigest())
    hh3.update('hello')
    hh3.update('hello')
    print(hh3.hexdigest())

使用多次 update 运行结果也是相同的

全部代码

您需要先支付 29.9元 才能查看此处内容!立即支付

注意该订单不支持退款,如有问题可联系博主

暂无评论
本文作者:
本文链接: https://www.qinless.com/?p=1300
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 qinless 的博客!
100

发表评论

返回顶部