大家好,欢迎来到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,后续用0;
- 至少填充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