2024年4月29日发(作者:)

WINRAR加密中SHA1算法原理及其密钥产生过程

1 SHA1算法简介

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature

St&ard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于

2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要

可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产

生不同的消息摘要。

SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消

息摘要。

2 术语和概念

2.1位(Bit),字节(Byte)和字(Word)

SHA1始终把消息当成一个位(bit)字符串来处理。本文中,一个“字”(Word)是32

位,而一个“字节”(Byte)是8位。比如,字符串“abc”可以被转换成一个位字符串:01100001

01100010 01100011。它也可以被表示成16进制字符串: 0x616263.

2.2 运算符和符号

下面的逻辑运算符都被运用于“字”(Word)

X&Y = X, Y逻辑与

X | Y = X, Y逻辑或

X ^ Y= X, Y逻辑异或

~X = X逻辑取反

X+Y定义如下:

字 X 和 Y 代表两个整数 x 和y, 其中 0 <= x < 2^32 且 0 <= y < 2^32. 令整数z = (x

+ y) mod 2^32. 这时候 0 <= z < 2^32. 将z转换成字Z, 那么就是 Z = X + Y.

循环左移位操作符Sn(X)。X是一个字,n是一个整数,0<=n<=32。Sn(X) =

(X<>32-n)

X<

右边的n位(最后结果还是32位)。X>>n是抛弃右边的n位,将各个位依次向右移动n位,

然后在左边的n位填0。因此可以叫Sn(X)位循环移位运算

3 SHA1算法描述

在SHA1算法中,我们必须把原始消息(字符串,文件等)转换成位字符串。SHA1算

法只接受位作为输入。假设我们对字符串“abc”产生消息摘要。首先,我们将它转换成位字

符串如下:

01100001 01100010 01100011

―――――――――――――

„a‟=97 „b‟=98 „c‟=99

这个位字符串的长度为24。下面我们需要5个步骤来计算MD5。

3.1 补位

消息必须进行补位,以使其长度在对512取模以后的余数是448。也就是说,(补位后

的消息长度)%512 = 448。即使长度已经满足对512取模后余数是448,补位也必须要进行。

补位是这样进行的:先补一个1,然后再补0,直到长度满足对512取模后余数是448。

总而言之,补位是至少补一位,最多补512位。还是以前面的“abc”为例显示补位的过程。

原始信息: 01100001 01100010 01100011

补位第一步:01100001 01100010 01100011 1

首先补一个“1”

补位第二步:01100001 01100010 01100011 10…..0

然后补423个“0”

我们可以把最后补位完成后的数据用16进制写成下面的样子

61626380 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000

现在,数据的长度是448了,我们可以进行下一步操作。

3.2 补长度

所谓的补长度是将原始数据的长度补到已经进行了补位操作的消息后面。通常用一个

64位的数据来表示原始消息的长度。如果消息长度不大于2^64,那么第一个字就是0。在

进行了补长度的操作以后,整个消息就变成下面这样了(16进制格式)

61626380 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000018

如果原始的消息长度超过了512,我们需要将它补成512的倍数。然后我们把整个消息

分成一个一个512位的数据块,分别处理每一个数据块,从而得到消息摘要。

3.3 使用的常量

一系列的常量字K(0), K(1), ... , K(79),如果以16进制给出。它们如下:

Kt = 0x5A827999 (0 <= t <= 19)

Kt = 0x6ED9EBA1 (20 <= t <= 39)

Kt = 0x8F1BBCDC (40 <= t <= 59)

Kt = 0xCA62C1D6 (60 <= t <= 79).

3.4 需要使用的函数

在SHA1中我们需要一系列的函数。每个函数ft (0 <= t <= 79)都操作32位字B,C,D

并且产生32位字作为输出。ft(B,C,D)可以如下定义

ft(B,C,D) = (B & C) or ((~ B) & D) ( 0 <= t <= 19)

ft(B,C,D) = B ^ C ^ D (20 <= t <= 39)

ft(B,C,D) = (B & C) or (B & D) or (C & D) (40 <= t <= 59)

ft(B,C,D) = B ^ C ^ D (60 <= t <= 79).

3.5 计算消息摘要

必须使用进行了补位和补长度后的消息来计算消息摘要。计算需要两个缓冲区,每个都

由5个32位的字组成,还需要一个80个32位字的缓冲区。第一个5个字的缓冲区被标识

为A,B,C,D,E。第一个5个字的缓冲区被标识为H0, H1, H2, H3, H4

。80个字的缓冲区被标识为W0, W1,..., W79

另外还需要一个一个字的TEMP缓冲区。

为了产生消息摘要,在第4部分中定义的16个字的数据块M1, M2,..., Mn

会依次进行处理,处理每个数据块Mi 包含80个步骤。

在处理每个数据块之前,缓冲区 被初始化为下面的值(16进制)

H0 = 0x67452301

H1 = 0xEFCDAB89

H2 = 0x98BADCFE

H3 = 0x10325476

H4 = 0xC3D2E1F0.

现在开始处理M1, M2, ... , Mn。为了处理 Mi,需要进行下面的步骤

(1). 将 Mi 分成 16 个字 W0, W1, ... , W15, W0 是最左边的字

(2). 对于 t = 16 到 79 令 Wt = S1(Wt-3 ^ Wt-8 ^ Wt- 14 ^ Wt-16).

(3). 令 A = H0, B = H1, C = H2, D = H3, E = H4.

A

t

B

t

C

t

D

t

E

t

ft(B,C,D)

S5

S30

Wt

Kt

A

t+1

B

t+1

C

t+1

D

t+1

E

t+1

(4) 对于 t = 0 到 79,执行下面的循环

TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;

E = D; D = C; C = S30(B); B = A; A = TEMP;

(5). 令 H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.

在处理完所有的 Mn, 后,消息摘要是一个160位的字符串,以下面的顺序标识

H0 H1 H2 H3 H4.

对于SHA256,SHA384,SHA512。你也可以用相似的办法来计算消息摘要。对消息进行

补位的算法完全是一样的。

4.布尔函数的性质

4.1 ft(B,C,D) = (B & C) or ((~ B) & D) ( 0 <= t <= 19)

ft(B,C,D)=ft(~B,C,D)

ft(B,C,D)=ft(B,C,~D)=C

<=>

<=>

<=>

C=D

B=0

B=1

ft(B,C,D)=ft(B,~C,D)=D

4.2 ft(B,C,D) = B ^ C ^ D (20 <= t <= 39)

ft(B,C,D)=~ft(~B,C,D)=~ft(B,~C,D)=~ft(B,C,~D)

ft(B,C,D)=ft(~B,~C,D) =ft(~B,C,~D)=ft(B,~C,~D)

4.3 ft(B,C,D) = (B & C) or (B & D) or (C & D) (40 <= t <= 59)

ft(B,C,D)=ft(~B,C,D) <=> C=D

ft(B,C,D)=ft(B,~C,D) <=> B=D

ft(B,C,D)=ft(B,C,~D) <=> B=C

4.4 ft(B,C,D) = B ^ C ^ D (60 <= t <= 79).

ft(B,C,D)=~ft(~B,C,D)=~ft(B,~C,D)=~ft(B,C,~D)

ft(B,C,D)=ft(~B,~C,D) =ft(~B,C,~D)=ft(B,~C,~D)

6 WINRAR的AESInit及AESKey产生过程

typedef struct {

uint32 state[5];//5个寄存器

uint32 count[2];//数据的位数,64位整数,count[0]为低32位,count[1]为高32位,

unsigned char buffer[64];

} hash_context;

PassWord[]={pw1,pw2,pw3…,pwn};//pwi为密码字符

SALT[]={s1,s2,s3,…,s8};//固定8字节长,在文件名加密的RAR文件0x14位置

RawPsw[]={pw1,0,pw2,0,pw3,0,…,pwn,0,s1,s2,s3,…,s8};

初始化hash_context c;//标准SHA1算法初值

for(i=0;i<0x40000;i++)

{

{

}

}

将c中剩余的未处理数据按规则补位至448位,再将数据总长度(字节数,8字节长)加到

数据尾部,完成SHA1的处理

for(i=0;i<4;i++)AESKey[i]=[i];

hash_context tempc=c;

将tempc中剩余的未处理数据按规则补位至448位,再将数据总长度(字节数,8字节

AESInit[i2]=[4]&0xff;

uchar i0,i1,i2;//i0,i1,i2为i的从低到高的三个字节值

RawPswhash[] = RawPsw[]+{i0,i1,i2}

Length_ RawPswhash = RawPswhash的长度;

对RawPswhash前面每段64字节进行SHA1标准处理,剩余不足64字节的数据暂不处

if(i0==0 且 i2==0)

理;

长)加到数据尾部,完成SHA1的处理