散列函数与消息认证码

图解密码技术学习笔记-散列函数与消息认证码

单向散列函数

概念与性质

  单向散列函数,又称单向 Hash 函数、杂凑函数,就是把任意长的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种函数。

  单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。散列值的长度与消息的长度无关。具有以下性质:

  • 根据任意长度的消息计算出固定长度的散列值;
  • 能够快速计算出散列值;
  • 消息不同散列值也不同;
  • 具备单向性,即无法通过散列值反算出消息。

  密码学中使用的单向散列函数,不仅要具备弱抗碰撞性,还必须具备强抗碰撞性。

  • 抗碰撞性:难以发现碰撞的性质称为”抗碰撞性”。
  • 弱抗碰撞性:给定某条消息的散列值,必须保证要找到和这条消息相同散列值的另一条消息是非常困难的。
  • 强抗碰撞性:要找到散列值相同的两条不同的消息是非常困难的。

  单向散列函数输出的散列值也称为消息摘要或者指纹。消息的完整性也叫一致性。

实例
  • MD4、MD5(128位,其强抗碰撞性已经被攻破)
  • SHA-1(160位,其强抗碰撞性已经被攻破)、SHA-256、SHA-384、SHA-512
实际应用
  • 检测软件是否被篡改

    软件发布者将散列值公开发布到网上,使用软件的人就可以根据这个来判断获得的软件是否已经被篡改。

  • 基于口令的加密
    PBE(Password Based Encryption)基于口令的加密,是将口令和salt(随机数)混合后计算其散列值,作为加密的密钥。这样可以抵御针对口令的字典攻击。

  • 消息认证码
    消息认证码是将”发送者和接收者之间的共享密钥”和”消息”进行混合计算出的散列值。使用消息认证码可以检测并防止通信过程中的错误、篡改以及伪装。在SSL/TLS中得到了运用。

  • 数字签名
    数字签名非常的耗时,所以不会对整个消息进行数字签名。一般先计算出消息的散列值,然后再针对散列值进行数字签名。

  • 伪随机数生成器
    伪随机数需要具备”事实上不可能根据过去的随机数列预测未来的随机数列”这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。

  • 一次性口令
    一次性口令通常被用于服务器对客户端的合法性认证。这种方式中,通过使用单向散列函数可以保证口令只在通信链路上传送一次,因此即使窃听者窃取了口令,也无法使用。

攻击
  • 暴力破解。本质是破解弱抗碰撞性。针对某一特定的消息找到与其相同的散列值的消息进行替换。从消息的冗余性入手,即在不改变消息意思的前提下能够对文件内容进行修改的程度,只要找到一份跟原文相同的散列值即可。
  • 生日攻击。本质是破解强抗碰撞性。所谓的生日攻击就是:随机选出N个人,其中任意两个人的生日相同的概率大于二分之一,请问N为多少?在这里,攻击是指,只要任何两份文档存在相同的散列值时,即可达成攻击。编写消息的人是攻击者。攻击者首先生成两份散列值相同,但内容不同的文件。其中一份要B支付1百万的合同给了A,A生成散列值后发送给B。攻击者截获此报文后,替换成散列值相同的要B支付1亿元的合同。
无法解决的问题

  单向散列函数能够辨别出篡改,但无法识别出伪装,也就是无法判断出发送消息的人是否是正确的。

消息认证码

概念

  消息的认证指的是消息来自正确的发送者。消息认证码是一种与密钥相关的单向散列函数。单向散列函数保证了完整性,无法被篡改;共享密钥只有发送者和接收者知道,保证了可以检查发送者身份的正确性。

  消息认证码的输入是任意长度的消息和一个发送者与接收者之间共享的密钥输出是固定长度的数据,这个数据称为MAC值。

  消息认证码同时解决消息的完整性和发送者正确性。

  • 消息完整性解决的是消息是否有被篡改的问题,也就是保证了消息的完整性。
  • 消息认证解决的是消息的发送者正确性的问题,确保消息不是其他人伪装发送的。
使用过程
  • 发送者发送消息后,使用发送的消息和共享密钥计算出 MAC 值,并发送给接收者;
  • 接收者接收到消息后,使用接收到的消息和共享密钥计算出 MAC 值;
  • 接收者接收到 MAC 值后,使用接收到的 MAC 值和自己计算的 MAC 值做比对。如果相同,则表示消息没有被篡改,且发送者的身份正确。
实现方式
  • 使用 SHA-1 等单向散列函数实现,其中一种实现方式为 HMAC。
  • 使用 AES 等分组密码实现。
    • 分组的密钥作为共享密钥。
    • 使用 CBC 模式进行加密。CBC 模式就是前一个分组的密文与此分组的明文 XOR 后,再加密生成当前分组的密文。
    • 由于不需要进行解密,所以只保留最后一个分组。由于最后一个分组会受到密钥和整个消息的双重影响,所以可以作为消息认证码。
  • 流密码和公钥密码也可以实现消息认证码。
应用实例
  • SWIFT

  用于银行与银行之间传递交易消息,使用了消息认证码保障完整性和对消息进行验证。共享密钥在使用公钥密码之前,是用人进行配送的。

  • IPsec

  针对 IP 协议增加安全性的一种方式,使用消息认证码对消息内容进行认证和保证完整性。

  • SSL/TLS

  安全套接字协议和安全传输层协议。

攻击
  • 重放攻击

  攻击者可以截获发送者的消息和 MAC 值,然后对接收者重放发送。这时虽然攻击者没有破解消息认证码,但对于接收者来说消息和 MAC 值是匹配的,所以还是会执行。解决的办法:

  • 序号。增加一个流水号,每次都加1。有效果,但是通信双方都需要记录最后一个消息的序号。
  • 时间戳。发送消息中包含当前时间,如果收到以前的消息则当做错误消息不执行。有效果,但是通信双方的时钟必须一致,不一致也会留下重放攻击的空间。
  • Nonce。先发送一个伪随机数(称为 Nonce),然后发送消息计算 MAC 值时包含 Nonce。由于每次通信 Nonce 都会发生变化,也就无法进行重放攻击。此办法的缺点是增加了通信量。
  • 密钥推测攻击

  如果是单向散列函数来进行生成 MAC,则使用攻击单向散列函数的暴力破解和生日攻击来完成攻击。

无法解决的问题
  • 对第三方认证

  如果接收者想要让第三方来认证发送者,这点是没法办到的。因为共享密钥只有一个,对于第三方来说无法通过共享密钥来判断到底哪个是发送者,哪个是接收者。

  • 防止否认

  发送者可以否认自己发送过消息,通过消息认证码是无法防止否认的。

坚持原创技术分享,您的支持将鼓励我继续创作!