SHA1算法详解

0x00 前言

SHA1算法也是哈希算法的一种,只要理解了MD5算法,SHA1也很快就能理解。
MD5算法可以参考:MD5算法详解
MD5算法得出的MD5值长度为16个字节(8*16=128位)
SHA1算法得出的SHA1值长度为20个字节(8*20=160位)

0x01 填充信息

和MD5算法类似,对信息的第一步也是填充信息直至满足条件。

填充的过程如下:
1.先判断文件(消息)的大小(长度) mod 512 == 448 mod 512 ,就是大小(长度)对512求余等于448。(这里的512、448是“位”为单位,转成“字节”就是64、56,即mod 64 == 56 mod 64)

2.如果大小(长度)满足 mod 512 == 448 mod 512,就在文件(消息)的末尾处添加64位(8字节)的值,值的内容是原消息的长度(以位为单位)

3.如果大小(长度)不满足要求,就执行以下操作:
(1)填充1个1
(2)填充0,直到满足满足过程的第一步。

注意:这里是以位为单位,假如是以字节为单位,第一个填充的是0x80(1000 0000),然后就填0x0
举例:消息内容为“gnubd”,就能得到以下内容

67 6E 62 75 64 80 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 

还需要注意到的是最后原消息的长度是以大端存储的方式存到内存中的,这里与MD5的存储是有区别的。

0x02 数据说明

这里列举出所用到的数据

DWORD sha1::A = 0x67452301;
DWORD sha1::B = 0xEFCDAB89;
DWORD sha1::C = 0x98BADCFE;
DWORD sha1::D = 0x10325476;
DWORD sha1::E = 0xC3D2E1F0;

这里相对MD5算法多了4个字节。(因为SHA1值就是比MD5值多4个字节嘛)

常量:

DWORD sha1::k[4] = {0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};

MD5就有64个,这个就简单一点,4个

0x03 处理信息

和MD5算法类似,也是需要将消息分组,每64个字节(512位)一组,分成多个组(n个)。
对与每一组 Mi M i (0 < i <= n)都要做如下处理。
将64个字节分成16组 w0 w 0 - w15 w 15 ,每组刚好4个字节
然后生成 w16 w 16 - w79 w 79 ,生成的方法如下:

for(DWORD i = 16;i<80;i++){
        DWORD temp = w[i-3]^w[i-8]^w[i-14]^w[i-16];
        w[i] = temp<<1 | temp>>31;
    }

接下来就是做核心运算了。
将a、b、c、d、e分别赋值为上面的A、B、C、D、E,作为 Mi M i 的初始值
然后循环80次,从0-79:

        for(DWORD j = 0;j<80;j++){
                DWORD temp;
                DWORD temp2 = a<<5|a>>27; //循环左移5位,等下需要用到
                switch(j/20){   
                case 0:   //0-19步执行这里
                    temp = (b&c)|((~(b))&d);
                    temp += sha1::k[0];  //这个是常数
                    break;
                case 1:  //20-39步执行这里
                    temp = (b^c^d);
                    temp += sha1::k[1];
                    break;
                case 2: //40-59步执行这里
                    temp = (b&c)|(b&d)|(c&d);
                    temp += sha1::k[2];
                    break;
                case 3: //60-79步执行这里
                    temp = (b^c^d);
                    temp += sha1::k[3];
                    break;
                }
                temp += temp2 + e + w[j]; //这里就是上面生成的80个分组了
                e = d;
                d = c;
                c = b<<30 | b>>2; //循环左移30位
                b = a;
                a = temp;
            }
        A+=a;
        B+=b;
        C+=c;
        D+=d;
        E+=e;

注意最后这里和MD5类似,也是再将abcde分别加上初始值ABCDE,作为下一个消息分组 Mi+1 M i + 1 的初始值,直到最后一个分组 Mn M n 计算完后,得出的结果就是SHA1值。
即:
MnAMnBMnCMnDMnE M n A M n B M n C M n D M n E
这里只需按直接输出就好了,不必像md5那样调整字节位置后再输出,

  • 10
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值