11.密码学哈希函数
-
总结密码学哈希函数的应用:消息认证、数字签名、生成单向口令文件。
-
解释使用哈希函数认证消息时要保证其安全性的原因:
防止哈希函数被破译。
- 哈希冲突会导致攻击者对消息进行篡改。
- 逆向计算:哈希函数不够复杂会导致攻击者反向计算出消息内容。
-
抗原像攻击、抗第二原像攻击、抗强碰撞攻击区别:
- 抗原像攻击:保证哈希函数的单向性。
- 抗第二原像攻击:对任意 x x x ,不存在 y ≠ x y\ne x y=x 但 H ( x ) = H ( y ) H(x) = H(y) H(x)=H(y)。
- 抗强碰撞攻击:不存在点对 ( x , y ) (x,y) (x,y),使得 x ≠ y x \ne y x=y 且 H ( x ) = H ( y ) H(x) = H(y) H(x)=H(y)。
-
如何使用分组密码链接构建哈希函数:(自制哈希)
- 选择一种分组密码算法(AES)和初始向量 Ⅳ。
- 对于第一个块,将初始向量 Ⅳ 与块数据加密,并将加密结果作为下一块的初始向量。
- 以此类推,最后一个快的加密结果构建的哈希函数的输出值。
H = E ( B l o c k n , E ( B l o c k n − 1 , . . . , E ( B l o c k 2 , E ( B l o c k 1 , Ⅳ ) ) ) ) H = E(Block_n,E(Block_{n-1},...,E(Block_2,E(Block_1,Ⅳ)))) H=E(Blockn,E(Blockn−1,...,E(Block2,E(Block1,Ⅳ))))
-
SHA-512运算过程:
- 附加填充位
- 附加128位长度信息在填充消息后
- 初始化缓冲区
- 以128字节分组为单位处理消息
- 输出
-
生日攻击:构造大量的随机输入数据,产生哈希碰撞。最大数据为 2 n / 2 2^{n/2} 2n/2 。
11.1 密码学哈希函数的应用
哈希函数举例:
-
每个分组按位异或。
-
密文分组链接(CBC):
- 对 X 1 , X 2 , . . . , X N ∈ M X_1,X_2,...,X_{N} \in M X1,X2,...,XN∈M ,哈希码 h = H ( M ) h = H(M) h=H(M) 定义为所有分组的异或:
h = X N + 1 = X 1 ⊕ X 2 ⊕ . . . X N h = X_{N+1} = X_1 \oplus X_2 \oplus ... X_{N} h=XN+1=X1⊕X2⊕...XN
11.1.1消息认证
验证消息完整性的机制或服务。
验证消息完整性步骤:
- 发送方根据消息使用哈希函数计算哈希值。
- 接收方收到消息后对其进行同样的哈希计算。
- 两次结果相比较,看是否一致。
消息认证方案:
- 使用对称密码算法 E 加密消息和哈希码。
- 只使用对称密码算法 E 加密哈希码。
- 只用哈希函数,不用加密算法。
11.1.2 数字签名
操作类似MAC,使用用户的私钥加密消息的哈希值,知道公钥的用户可以验证消息的完整性。
11.2 哈希函数要求与安全性
密码学哈希函数H的安全要求:
要求 | 描述 |
---|---|
输入长度可变 | H适用于任意长度的数据分组 |
输出长度固定 | H 生成定长的输出 |
效率 | H ( x ) H(x) H(x) 对任意 x x x 都很容易计算 |
抗原像攻击(单向性) | 对任意 x x x ,找到满足 H ( y ) = h H(y) = h H(y)=h 在计算上不可行 |
抗第二原像攻击(抗弱碰撞性) | 对任意分组 x x x , 计算上不存在 y ≠ x y \ne x y=x ,但 H ( x ) = H ( y ) H(x) = H(y) H(x)=H(y) |
抗碰撞攻击(抗强碰撞性) | 计算上找不到任何点对 ( x , y ) (x,y) (x,y) ,同时满足 x ≠ y x \ne y x=y 和 H ( x ) = H ( y ) H(x) = H(y) H(x)=H(y) |
伪随机性 | H 的输出满足伪随机性测试标准 |
- 前三条性质为实际应用哈希函数的要求。
- 满足前五条性质为弱哈希函数。
- 满足前六条性质为强哈希函数。(哈希+数字签名、MAC要求满足强哈希函数)
哈希函数三条性质之间的关系:
11.3 安全哈希算法(SHA)
算法输入:最大长度小于 2 128 2^{128} 2128 位的消息,处理时以1024位为一组。
算法输出:512位消息摘要。
算法步骤:
-
附加填充位:
- 填充消息,使消息长度 l e n g t h length length 满足 l e n g t h = 1024 ∗ N − 128 length = 1024*N - 128 length=1024∗N−128。(无论原先是否满足该条件都要填充)
- 填充由一个 1 和后续若干 0 组成。
-
附加长度:
- 在消息后附加一个128位的分组,使 l e n g t h = N ∗ 1024 length = N*1024 length=N∗1024。
-
初始化哈希缓冲区:
-
哈希函数的中间结果和最终结果保存在512位的缓冲区中,缓冲区用8个64位寄存器(a,b,c,d,e,f,g,h)表示。
寄存器号 初始值 a 2 \sqrt 2 2 小数部分前64位的十六进制。 b 3 \sqrt 3 3 小数部分前64位的十六进制。 c 5 \sqrt 5 5 小数部分前64位的十六进制。 d 7 \sqrt 7 7 小数部分前64位的十六进制。 e 1 1 \sqrt 11 11 小数部分前64位的十六进制。 f 1 3 \sqrt 13 13 小数部分前64位的十六进制。 g 1 7 \sqrt 17 17 小数部分前64位的十六进制。 h 1 9 \sqrt 19 19 小数部分前64位的十六进制。
以1024位(128字节)的分组为单位处理消息。
- 运算公式如下:
(Ⅳ为缓冲区的初始值,MD表示最后输出的消息摘要,SUM表示对输入对中的每个字单独进行模 2 64 2^{64} 264加。)
-
H 0 = Ⅳ H i = S U M 64 ( H i − 1 , a b c d e f g h i ) M D = H N H_0 = Ⅳ\\\\H_i = SUM_{64}(H_{i-1},abcdefgh_i) \\\\MD = H_{N} H0=ⅣHi=SUM64(Hi−1,abcdefghi)MD=HN
- 输出:输出 512 位的消息摘要。
*MD**表示最后输出的消息摘要,SUM表示对输入对中的每个字单独进行模 2 64 2^{64} 264加。)
H 0 = Ⅳ H i = S U M 64 ( H i − 1 , a b c d e f g h i ) M D = H N H_0 = Ⅳ\\\\H_i = SUM_{64}(H_{i-1},abcdefgh_i) \\\\MD = H_{N} H0=ⅣHi=SUM64(Hi−1,abcdefghi)MD=HN
- 输出:输出 512 位的消息摘要。