sha1算法笔记

sha1算法笔记根据 FIPS180 4 学习 sha1 算法

大家好,欢迎来到IT知识分享网。

1. 简介

Secure Hash Algorithm(SHA)是美国联邦信息处理标准(FIPS)认证的安全散列算法,对应FIPS 180系列标准。

SHA1:

  • 于4/17/1995发布,取代SHA0 (FIPS 180);
  • 设计上借鉴了MD4/5;
  • 摘要长度:160bits == 20 bytes, H0~H4,比MD5多4个字节(1 word);
  • 消息长度:<2^64 bits
  • 分组长度:512 bits == 64 bytes
  • 字(word)长:32 bits == 4 bytes
  • 运算步骤数:80,比MD5多16步;
  • 强抗碰撞性于2005年被王小云攻破;

2. 算法流程

本部分参考FIPS 180-4整理,标号与文档保持一致。

4. FUNCTIONS AND CONSTANTS

4.1.1 SHA-1 FUNCTIONS

// f(x,y,z) // x, y, z : 4-byte words // t: operation index #define CH(x,y,z) ((x & y) ^ (~x & z)) / 0 <= t <= 19 / #define PARITY(x,y,z) (x ^ y ^ z) / 20 <= t <= 39 and 60 <= t <= 79 / #define MAJ(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) / 40 <= t <= 59 / 

在FIPS 180-1中,宏函数命名为F0, F1, F2, F3, FIPS 180-2才使用了上述3个命名。

SHA1一共80轮运算,参数t即代表当前是第几轮。

4.2.1 SHA-1 CONSTANTS

#define Kx 0x5a / 0 <= t <= 19 / #define Ky 0x6ed9eba1 / 20 <= t <= 39 / #define Kz 0x8f1bbcdc / 40 <= t <= 59 / #define Kw 0xca62c1d6 / 60 <= t <= 79 / 

5. PREPROCESSING

5.1 Padding the Message

该部分填充方法,适用于MD5, SHA-1, SHA-224 and SHA-256。

第一步,填充数据,使位长度比512的倍数小64。

bitsLen == 448 mod 512 bytesLen == 56 mod 64 

填充方法:

  1. 一个1,后续用0;
  2. 至少填充1 bit,至多512 bits (64 bytes)。

第二步,添加64 bits消息长度。

经过这一步,消息长度就是512 bits (16 words)的倍数了。

以消息”abcde”为例:

 65 

经过前两步后,数据如下:

  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028. 

5.2 Parsing the Message

对于SHA-1, SHA-224,SHA-256,可将数据分为N个长512 bit的分组(block),每块可根据个人编码习惯表示为如下形式:

#define BLOCK_SIZE 64 uint8_t M[BLOCK_SIZE]; uint32_t M[BLOCK_SIZE/4]; // 16 32-bit words, 

5.3 Setting the Initial Hash Value

uint32_t h[5]; h[0] = 0x; h[1] = 0xefcdab89; h[2] = 0x98badcfe; h[3] = 0x; h[4] = 0xc3d2e1f0; 

该初始hash会随之数据块的处理而更新,最终结果就是sha1。

FIPS 180将它们的副本命名为a,b,c,d,e

6.1.2 SHA-1 Hash Computation

Prepare the message schedule

根据64字节数据块生成数组W:

uint32_t W[80] = { 
   0}; if ( 0 <= t && t <= 15) { 
    W[t] = M[t]; } else if (16 <= t && t <= 79) { 
    W[t]=ROTL1( W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16] ); } 

W数组长80,但在实际运行中,16个元素足以,可以优化一下:

// 可以把W想象成一个滑动窗口 uint32_t W[16] = { 
   0}; if ( 0 <= t && t <= 15) { 
    W[t] = M[t]; } else if (16 <= t && t <= 79) { 
    // index = t mod 0xFF  W[t&0xFF]=ROTL1( W[(t-3)&0xFF] ^ W[(t-8)&0xFF] ^ W[(t-14)&0xFF] ^ W[t&0xFF] ); } 

这里处理时有个注意事项。消息块M应该是这样定义的:

uint8_t M[64]; 

而W则是uint32_t类型数组。根据FIPS 180-4 3.1章节的说明,SHA算法都是按照大端序存储整型的。

3.1 Bit Strings and Integers

Initialize the five working variables

a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4]; 

80 x f(x,y,z)

伪代码:

For t=0 to 79: { 
    Temp = ROTL5(a) + f(b,c,d) + e + Kt + W[t]; e = d; d = c; c = ROTL30(b); // 循环左移  b = a; a = Temp; } 

80次运算,根据W数组和f函数(常数K与f分段一致),可以分成5轮:

W[t] = M[t] F = CH Round 0 -15 W[t]=ROTL1(...) F = CH Round 16-19 F = PARITY Round 20-39 F = MAJ Round 40-59 F = PARITY Round 60-79 

Compute the intermediate hash value

80次运算后,更新中间hash值:

h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; 

拼接输出sha1

处理完所有消息后,拼接h数组即为最终sha1:

for (i=0; i < 5; ++i) { 
    printf("%02X", h[i]); } 

3. 实现

https://github.com/C0deStarr/CryptoImp/tree/main/Hash/sha

参考资料

https://csrc.nist.gov/publications/detail/fips/180/4/final

https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/134458.html

(0)
上一篇 2025-07-12 13:26
下一篇 2025-07-12 13:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信