总体上来说,SHA1算法和MD5算法很类似(因为它们都属于是针对于信息摘要的哈希算法),大体的算法流程也是基本相同,可以回忆下MD5算法的五个步骤,可以说SHA1是升级版本的MD5。不同点从直观上看,SHA1返回的信息长度是160位(20个字节),而MD5则是128位(16个字节),因此相较于MD5算法来说会更加安全一些(不过也仅仅是一些而已)
算法流程就不多做介绍,和MD5算法类似,同样需要通过五个步骤来完成
基本一样,不做额外说明
同上
这一步开始有不同了,SHA1算法也同样有初始变量,与MD5不同的是,MD5最终是依靠初始变量组合起来的16个字节的结果,而SHA1结果为20个字节,因此也在初始变量中多了4个字节,定义如下
uint32_t H0 = 0x67452301; // 0x01, 0x23, 0x45, 0x67
uint32_t H1 = 0xEFCDAB89; // 0x89, 0xAB, 0xCD, 0xEF
uint32_t H2 = 0x98BADCFE; // 0xFE, 0xDC, 0xBA, 0x98
uint32_t H3 = 0x10325476; // 0x76, 0x54, 0x32, 0x10
uint32_t H4 = 0xC3D2E1F0; // 0xF0, 0xE1, 0xD2, 0xC3
初始化变量的个数和结果有直接关系,因为结果是由初始化变量组合在一起的
这一步大体结构一样,但是处理的方式有点不同
分组方式不说了,同样是将数据处理成了N*512的分组形式,下面再对每个分组进行二次分组成16份,也就是16*32=512,每个子分组是32bit的数据,着重讲讲和MD5算法的不同点
相比于MD5的四轮计算,SHA1也会涉及到四轮计算,每轮则增加到20次,一共是80次非线性函数计算,对于每轮使用的数据和MD5也是有区别的,MD5处理每次分组的数据就是把数据分成16组,每轮使用的都是这16组数据,而SHA1则不一样,只有前16组使用的是拆分的数据,从16-80则根据公式得到新的数据
/* a. Divide M(i) into 16 words W(0), W(1), ..., W(15), where W(0) is the left - most word. */
for (t = 0; t <= 15; t++)
{
W[t] = M[t];
}
/* b. For t = 16 to 79 let
W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). */
for (t = 16; t <= 79; t++)
{
W[t] = MoveLeft(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
首先先看看四个非线性函数参考(二、四轮其实是一样的)
/* f(X, Y, Z) */
/* [0, 19] */
static uint32_t Ch(uint32_t X, uint32_t Y, uint32_t Z)
{
return (X & Y) ^ ((~X) & Z);
}
/* [20, 39] */ /* [60, 79] */
static uint32_t Parity(uint32_t X, uint32_t Y, uint32_t Z)
{
return X ^ Y ^ Z;
}
/* [40, 59] */
static uint32_t Maj(uint32_t X, uint32_t Y, uint32_t Z)
{
return (X & Y) ^ (X & Z) ^ (Y & Z);
}
接着是每次计算所会涉及到的常量K,还记得在MD5中有个常量表T表,T表是根据公式计算得来的64个常量,而K就是直接给好的
K(t) = 5A827999 ( 0 <= t <= 19)
K(t) = 6ED9EBA1 (20 <= t <= 39)
K(t) = 8F1BBCDC (40 <= t <= 59)
K(t) = CA62C1D6 (60 <= t <= 79)
文档也给的很干脆,每轮一个固定常量
下面该讲到具体的处理了,MD5算法每次计算改变的只是一个变量的值,但是SHA1每次计算则会改变五个变量的值
uint32_t temp = MoveLeft(A, 5) + Ch(B, C, D) + E + W[t] + K[0];
E = D;
D = C;
C = MoveLeft(B, 30);
B = A;
A = temp;
最终只需要将得到的a、b、c、d重新赋值再作为初始变量传递给下一分组计算即可
在经过分组计算后能够得到A、B、C、D、E,从低位字节A开始,高位字节E结束
文中每个步骤都在对比MD5和SHA1的异同,可以看出,虽然结果上SHA1只是多了4个字节,但是在细节上还是有很大的提升,算法整体上更复杂了,变化也更多了,下面总体归纳下两个算法的异同
算法 | MD5 | SHA1 |
---|---|---|
分组数据处理 | 使用同一套16组数据 | 基于16组数据的基础上变化得到额外64组数据 |
初始化常量 | 4个 | 5个 |
非线性函数 | 4个 | 4个 |
常量表 | T常量表分配给64次计算,各不相同 | K表分配给80次计算,每20次使用同一个常量 |
常量变化 | 每次计算重新给一个常量赋值 | 每次计算所有常量全部发生变化 |