跳到主要内容

读《深入浅出密码学》

第一部分 密码原语​

第1章 引言​

协议的安全依赖密钥,而与算法本身是否保密无关。

Diffie-Hellman密钥交换算法:A与B各自生成私钥和公钥,并交换公钥,使用对方的公钥和自己的私钥计算出共享密钥。敌手通过观察公钥不能获得私钥的任何信息,更不能计算出共享密钥。但面临着中间人攻击。

非对称加密RSA:公钥加密,公钥加密并用私钥解密;数字签名,私钥加密并用公钥解密。

常见攻击密码的方法:将密钥泄露给攻击者,在没有密钥的情况下解密消息,仅仅通过观察加密的消息就可以知道消息本身等。任何对算法假设的削弱可以认为算法被攻破。

第2章 哈希函数​

哈希函数可以给任何数据生成一个全局唯一的标识符,其输出通常被称为摘要(Digest)或哈希值(Hash),也被称为校验和(Checksum),可以用来校验文件的完整性和真实性。

哈希函数有以下特点:

  • 输入可以是任意大小,甚至可以是空值,而输出长度总是固定的
  • 给定相同的输入,哈希函数总能产生相同的输出
  • 无法求逆,无法从输出中找到输入(抗第一原像性,前提是输入空间不能太小且要具有不可预测性)
  • 抗第二原像性,也就是我们无法推断出另一个文件也可以通过同样的哈希函数得到相同的输出
  • 抗碰撞性,保证不能够生成哈希值相同的两个不同输入
  • 输出不可预测且随机

哈希函数使用的安全要求:

  • 为了满足抗碰撞性,摘要长度至少是256比特
  • 为了满足抗第一原像性和抗第二原像性,摘要长度至少是128比特

实际应用:

  • 承诺
  • 资源完整性

SHA-2哈希函数有不同版本:SHA-224、SHA-256、SHA-384、SHA-512。

SHA-2加密时首先对输入消息进行填充,使其长度是压缩函数输入长度的倍数;分组,使每组的长度相等;然后将压缩函数应用于消息的所有分组(压缩函数的输入为两个参数,两个参数经过加密和异或后得到输出),每次迭代过程中都将上一轮的输出作为压缩函数第二个输入参数,最后输出摘要。第一轮压缩函数的第二个输入参数IV在特定的算法中为常量。

SHA-2会受到长度扩展攻击,也就是SHA-2的摘要本身可以再作为压缩函数的输入。

置换是一一对应(双射)关系,可逆(可以根据输出找到输入),SHA-3建立在置换之上。

顾名思义,海绵结构的工作过程就像一块海绵吸水再挤水:

  • 吸水(Absorbing):把输入的消息(数据)一点点“吸”进海绵内部。
  • 挤水(Squeezing):把海绵里的水(哈希摘要)一点点“挤”出来。

海绵结构内部有一个固定长度的状态(State),通常记为bb位。这个状态被分为两部分:

  • 比特率(Rate,记为rr):这是每次真正与输入数据(或输出数据)进行异或运算的部分。
  • 容量(Capacity,记为cc):这部分不直接参与数据的输入输出,它是海绵的“安全缓冲区”。b=r+cb=r+c
  • 置换函数(Permutation,记为ff):这是海绵结构的核心,它是一个固定且可逆的复杂函数。每次吸收或挤出时,都会对内部整个状态bb调用一次这个函数。
  1. 填充:和 SHA-2 一样,先把输入消息进行填充,使其长度成为rr的整数倍。

  2. 异或:把消息分成rr位的块。将第一个消息块与状态的前rr位(比特率部分)进行异或(XOR)。

  3. 置换:对异或后的整个状态(bb位)应用置换函数ff。

  4. 重复:用下一个消息块重复上述异或和置换步骤,直到所有消息块都被“吸”完。

  5. 输出:取当前状态的前rr位(比特率部分)作为输出。

  6. 判断:如果需要的哈希长度还没达到,就对整个状态应用置换函数ff,然后再取前rr位输出。

  7. 重复:直到挤出足够长度的摘要。

SHAKE和cSHAKE可以提供长度可变的输出,可以使用元组哈希来避免模糊的哈希

口令哈希:

  • 加盐,避免暴力攻击和穷举搜索(彩虹表)
  • 使用口令哈希,运行速度很慢,避免快速破解

第3章 消息认证码MAC​

消息验证码算法的输入为密钥和信息,输出唯一的验证标签。

HMAC的原理如下:

输入参数为密钥k和待认证消息message:

k1=k⊕ipadk2=k⊕opadresult=hash(k2∥hash(k1∥message))\begin{aligned} k1 &= k \oplus ipad \\ k2 &= k \oplus opad \\ result &= hash(k2 \parallel hash(k1 \parallel message)) \end{aligned}

哈希函数可以是SHA-256、SHA-512等。

除此之外还有KMAC。

第4章 认证加密​