一、实验目的及要求
1. 掌握SHA-1算法的原理
2. 编写程序实现这个算法
二、实验设备(环境)及要求
PC机, VC++等
三、实验内容与步骤
- SHA-1(对代码中的主要内容进行分析讲解)
步骤:
- 对输入的字符串进行补位操作,因为Sha-1算法标准规定,必须对消息摘要进行补位操作,即将输入的数据进行填充,使得数据长度对512求余的结果为448,填充比特位的最高位补一个1,其余的位补0,如果在补位之前已经满足对512取模余数为448,也要进行补位,在其后补一位1即可。
- 在信息摘要后面附加64bit的信息,用来表示原始信息摘要的长度;
- 初始化缓存:
H0=0x67452301
H1=0xefcdab89
H2=0x98badcfe
H3=0x10325476
H4=0xc3d2e1f0
- 计算消息摘要:循环左移操作符Sn(x),x是一个字,也就是32bit大小的变量,n是一个整数且0<=n<=32。Sn(X) = (X<<n)OR(X>>32-n),和在程序中所要用到的常量,这一系列常量字k(0)、k(1)、...k(79),以及所要用到的一系列函数。
- 计算需要一个缓冲区,由5个32位的字组成,还需要一个80个32位字的缓冲区。第一个5个字的缓冲区被标识为A,B,C,D,E。80个字的缓冲区被标识为W0, W1,..., W79;
- 另外还需要一个一个字的TEMP缓冲区。
- 将 Mi 分成 16 个字 W0, W1, ... , W15, W0 是最左边的字
- 对于 t = 16 到 79 令 Wt = S1(Wt-3 XOR Wt-8 XOR Wt- 14 XOR Wt-16).
- 令 A = H0, B = H1, C = H2, D = H3, E = H4.
- 对于 t = 0 到 79,执行下面的循环
TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;
E = D; D = C; C = S30(B); B = A; A = TEMP;
- 令 H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.
代码:
#include "stdafx.h"
#include<stdio.h>
#include <string.h>
#include <conio.h>
#include <wtypes.h>
void creat_w(unsigned char input[64],unsigned long w[80])
{
int i,j;unsigned long temp,temp1;
for(i=0;i<16;i++)
{
j=4*i;
w[i]=((long)input[j])<<24 |((long)input[1+j])<<16|((long)input[2+j])<<8|((long)input[3+j])<<0;
}
for(i=16;i<80;i++)
{
w[i]=w[i-16]^w[i-14]^w[i-8]^w[i-3];
temp=w[i]<<1;
temp1=w[i]>>31;
w[i]=temp|temp1;
}
}
char ms_len(long a,char intput[64])
{
unsigned long temp3,p1; int i,j;
temp3=0;
p1=~(~temp3<<8);
for(i=0;i<4;i++)
{
j=8*i;
intput[63-i]=(char)((a&(p1<<j))>>j);
}
return '0';
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned long H0=0x67452301,H1=0xefcdab89,H2=0x98badcfe,H3=0x10325476,H4=0xc3d2e1f0;
unsigned long A,B,C,D,E,temp,temp1,temp2,temp3,k,f;int i,flag;unsigned long w[80];
unsigned char input[64]; long x;int n;
printf("input message:\n");
scanf("%s",input);
n=strlen((LPSTR)input);
if(n<57)
{
x=n*8;
ms_len(x,(char*)input);
if(n==56)
for(i=n;i<60;i++)
input[i]=0;
else
{
input[n]=128;
for(i=n+1;i<60;i++)
input[i]=0;
}
}
creat_w(input,w);
/*for(i=0;i<80;i++)
printf("%lx,",w[i]);*/
printf("\n");
A=H0;B=H1;C=H2;D=H3;E=H4;
for(i=0;i<80;i++)
{
flag=i/20;
switch(flag)
{
case 0: k=0x5a827999;f=(B&C)|(~B&D);break;
case 1: k=0x6ed9eba1;f=B^C^D;break;
case 2: k=0x8f1bbcdc;f=(B&C)|(B&D)|(C&D);break;
case 3: k=0xca62c1d6;f=B^C^D;break;
}
/*printf("%lx,%lx\n",k,f); */
temp1=A<<5;
temp2=A>>27;
temp3=temp1|temp2;
temp=temp3+f+E+w[i]+k;
E=D;
D=C;
temp1=B<<30;
temp2=B>>2;
C=temp1|temp2;
B=A;
A=temp;
//printf("%lx,%lx,%lx,%lx,%lx\n",A,B,C,D,E);//输出编码过程
}
H0=H0+A;
H1=H1+B;
H2=H2+C;
H3=H3+D;
H4=H4+E;
printf("\noutput hash value:\n");
printf("%lx%lx%lx%lx%lx",H0,H1,H2,H3,H4);
getch();
}
四、实验结果与数据处理
五、分析与讨论
经过这次实验,我明白了SHA-1的的特性(对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要)以及它的原理(遵循雪崩效应)
经过这次实现,我明白了它与MD5算法的差别:
(1)MD5是^128数量级的操作,而对SHA-1则是2^160数量级的操作,这样,SHA-1对强行攻击 有更大的强度
(2)不过在相同的硬件上,SHA-1的运行速度比MD5慢.
|