视频
杂凑函数(aka 哈希函数、报文摘要函数、散列函数等),是将任意长度的报文 m 压缩成固定长度的报文摘要 H(m) 的函数。
有两种杂凑函数,不带密钥的(MDC)、带密钥的(MAC)。
- 单向性(求第一原像不可行)。H(m)=z 可求,反之计算不可行。
- 弱无碰撞性(求第二原像不可行)。任意给定报文 m1 找出另一个不同报文 m2 使得 H(m1)=H(m2) 计算不可行。
- 强无碰撞性。任意两份报文杂凑值不同。
- 完整性检验。
- 数字签名。
- 密钥推导。
- 伪随机数生成。
目的是找到两个不同的 m1,m2 使得 H(m1)=H(m2)。
- 随机选取 N 个不同报文 m1,m2,m3,...,mN
- 计算这 N 个报文的杂凑值,得到集合
S={(mk,H(mk)):k=1,2,...,N}
- 根据 H(mk) 的大小,对集合 S 快速排序
- 若过程中找到两个不同消息使 H(mk)=H(mt) 就成功停止,否则失败停止
所需存储量:表 S 的规模 O(N)
所需计算量:
- 生成集合 S 的计算量为计算 N 次杂凑函数
- 快速排序并找出碰撞的计算量为 ∣N∣log2∣N∣ 次比较
成功率:
设杂凑值为 n bit 且 N 远小于 2n,则碰撞攻击的成功率近似为
1−e−2n+1N2
特别地,当 N=2n 时,碰撞成功率近似为
1−e−0.5≈1−2.7181≈0.393
特别地,当 N=2n+1 时,碰撞成功率近似为
1−e1≈1−2.7181≈0.632
所有 H(mk) 都不相同,完全没有碰撞的概率为
(1−2n1)(1−2n2)...(1−2nN−1)=i=1∏N−1(1−2ni)
由 1−x≈e−x 有(没有学过数分不懂,只能记结论)
i=1∏N−1(1−2ni)≈i=1∏N−1e2ni=e2n+1−N(N−1)≈e2n+1−N2
假设能对抗穷举攻击的密钥长度安全界限为 n,能够对抗碰撞攻击的杂凑函数安全界限为 2n。
将消息 M=(M1,M2,...,Mn) 的最后一个分组 Mn 设置为原始消息长度。
这样,H(0)=H(00)。
消息 M=(M1,M2,...,Mn),初始值 H0,Hi=E(Hi−1,Mi),i=1,2,...,n,最后得到 Hn 就是消息的杂凑值。也就是不断 update 初值至完整消息。
常见的杂凑函数设计如下

由 MD4 改进,产生 128 位输出,一个主循环处理 512 bit(长度 L,执行次数 t=L/512)
- 原始消息二进制后填一个 1,然后在最低 64 bit 填入原始消息长度的二进制,中间全部补 0,填充后长度为 512 bit 整数倍。长于 264时,模 264 直接填入后 64 bit。
- 将填充后结果 x 分为 t 个 512 bit 块 x0,x1,...,xt−1
- 将每个块 xi(i=0,1,...,t−1) 再划分为 16 个 32 bit 的子块,记为 M[16i]M[16i+1]...M[16i+16]
初始向量
- A = 0x01234567
- B = 0x89abcdef
- C = 0xfedcba98
- D = 0x76543210
F(X,Y,Z)=(X∧Y)∨(X∧Z)G(X,Y,Z)=(X∧Z)∨(Y∧Z)H(X,Y,Z)=X⊕Y⊕ZI(X,Y,Z)=Y⊕(X∨Z)
- 将 16 个子块放入缓存 X[j]
- 保存初始值为 AA,BB,CC,DD
- 数据块与 ABCD 刷新多轮
- 结果与原始值模 232 加(如 A′=A+AAmod232)
连接最后输出就是结果。
a←(b+[a+f(b,c,d)+x[i]+t]<<<s)
第二轮也是类似,将 f 变为 g。之后每一轮也是更换一个函数。
MD5 算法已被证明是不安全的。
以 SHA-512 为例。
- 原始消息二进制后填一个 1,然后在最低 128 bit 填入原始消息长度的二进制,中间全部补 0,使得填充后长度是 1024 整数倍。长于 2128时,模 2128 直接填入后 128 bit。
- 将填充结果分为 8 个 64 bit 块。
也有很多很多的初始向量,记忆这些东西没有意义,略过。
CH(x,y,z)=(x∨y)⊗((¬x)∨z)MAJ(x,y,z)=(x∨y)⊗(x∨z)⊗(y∨z)BSIG0(x)=ROTR28(x)⊗ROTR34(x)⊗ROTR39(x)BSIG1(x)=ROTR14(x)⊗ROTR18(x)⊗ROTR41(x)SSIG0(x)=ROTR1(x)⊗ROTR8(x)⊗SHR7(x)SSIG1(x)=ROTR19(x)⊗ROTR61(x)⊗SHR6(x)
T1=h+BSIG1(e)+CH(e,f,g)+Kt+WtT2=BSIG0(a)+MAJ(a,b,c)h=gg=ff=ee=d+T1d=cc=bb=aa=T1+T2
计算最终结果
Hi,0=a+Hi−1,0Hi,1=b+Hi−1,1Hi,2=c+Hi−1,2Hi,3=d+Hi−1,3Hi,4=e+Hi−1,4Hi,5=f+Hi−1,5Hi,6=g+Hi−1,6Hi,7=h+Hi−1,7
拼接 HN,0,HN,1,...,HN,7
基于海绵函数,我搞不懂。
有密钥 k 函数 H,两个包含 k 信息的数字串 k1,k2,计算消息 m 的认证码:HMAC(m)=Hk2(Hk1(m))
博客园文章