什么是 SHA ?
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)指的是密码散列函数家族。
是FIPS所认证的安全散列算法。
输入不同消息,能计算出一个长度固定的字符串算法(又称消息摘要)。
且不同的数字消息,很高机率对应到不同的字符串。
SHA 家族
SHA家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512。
由美国国家安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布。
SHA-224、SHA-256、SHA-384 和 SHA-512 有时并称为 SHA-2。
SHA-1在许多安全协定中广为使用,包括TLS和SSL、PGP、SSH、S/MIME 和 IPsec,曾被视为是MD5(更早之前被广为使用的杂凑函数)的后继者。
SHA-2 是比 SHA-1 更具安全性的进阶版本。
目前大多重视安全的产品,均由 SHA-1 更换至 SHA-2 。
SHA-0 and SHA-1
最初载明的算法于1993年发布,称做安全杂凑标准(Secure Hash Standard),FIPS PUB 180。这个版本常被称为SHA-0。
它在发布之后,很快就被NSA撤回。
并由1995年发布的修订版本FIPS PUB 180-1(即SHA-1)取代。
SHA-0 和 SHA-1 的算法只在压缩函数的讯息转换部分差了一个位元的循环位移。
根据 NSA 的说法,它修正了一个在原始算法中会降低杂凑安全性的弱点。
然而 NSA 并没有提供任何进一步的解释或证明该弱点已被修正。
而后 SHA-0 和 SHA-1 相继被攻破。
SHA-1似乎是显得比SHA-0有抵抗性,这多少证实了NSA当初修正算法以增进安全性的声明。
SHA-0和SHA-1可将一个最大2的64次方位元的讯息,转换成一串160位元的讯息摘要。
其设计原理相似于MIT教授Ronald L. Rivest所设计的密码学杂凑算法MD4和MD5。
应用
消息摘要是密码学中的一个重要概念,它能够将任意长度的数据转换为固定长度的摘要值。
消息摘要算法,也被称作散列算法,是一种单向加密算法,具有不可逆性。
即无法从摘要值恢复出原始数据。
消息摘要的特点
快速计算:消息摘要算法通常能够快速地计算出摘要值,适用于大数据量的处理。
固定长度:无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。
不可逆性:消息摘要是单向的,无法从摘要值恢复出原始数据。
唯一性 :只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同。
但相同的输入必会产生相同的输出。
实 现
这里以 SHA2 的 SHA256 为例。
函数需要用户提供以下要素:
1、长度32字节的数组,用以承接函数输出的[摘要]。
2、标注来源消息的长度数据。
3、一段来源消息,用来产生[摘要],最少是0字节,最大是 2^56 字节。
函数的第一步骤,是将[消息]重组,比如 ... ...
消息 = NULL,消息长度 = 0 bytes = 0 bits,那么重组后就是一个 chunk ... ...
0x80000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
消息 = 0x01, 0x23, 0x45,消息长度 = 3 bytes = 0x18 bits,那么重组后就是一个 chunk ... …
0x01234580 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000018
消息 = 0x12, ... ... ,消息长度 = 55 bytes = 0x01B8 bits,那么重组后就是一个 chunk ... …
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCD80 0x00000000 0x000001B8
消息 = 0x12, ... ... ,消息长度 = 56 bytes = 0x01C0 bits,那么重组后就是二个 chunk ... …
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x80000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x000001C0
消息 = 0x12, ... ... ,消息长度 = 64 bytes = 0x0200 bits,那么重组后就是二个 chunk ... …
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x01234567 0x89ABCDEF 0x01234567 0x89ABCDEF
0x80000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000200
函数的第二步骤,把一个 chunk 的 64 bytes 依[Big-endian],分割成 Word_00 ~ Word_15。
然后,第 16 words ~ 63 words 则是套用下方公式生成出来。
公式:Wt = σ0(Wt−15)+ σ1(Wt−2)+ Wt−16 + Wt−7
比如: Word_16 = W16 = σ0(W1)+ σ1(W14)+ W0 + W9
函数的第三步骤,准备好下方参考表。
Key 0~Key 3:0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
Key 4~Key 7:0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
Key 8~Key11:0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
Key12~Key15:0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
Key16~Key19:0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
Key20~Key23:0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
Key24~Key27:0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
Key28~Key31:0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
Key32~Key35:0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
Key36~Key39:0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
Key40~Key43:0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
Key44~Key47:0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
Key48~Key51:0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
Key52~Key55:0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
Key56~Key60:0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
Key60~Key63:0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
函数的第四步骤,依下方的图示进行运算。(t = 0 ~ 63)
其中 ... ...
上图,最上方的ABCDEFGH的初值是:
A = 0x6909e667
B = 0xbb67ae85
C = 0x3c6ef372
D = 0xa54ff53a
E = 0x510e527f
F = 0x9b05688c
G = 0x1f83d9ab
H = 0x5be0cd19
红色田字方块代表,将各个输入,以 Word 相加,不用理会进位。
比如:W0 = 0xFFFFFFFF,K0 = 0x00000001,相加之后就是 0x00000000。
Wt 就是[第二步骤]的 Word_0~Word_63。
Kt 就是[第三步骤]的 Key_0~Key_63。
其他的公式如下图 ... …(符号说明)
¬ = 取 1 补数,即 1 变 0,0 变 1。
⊕ = XOR
∧ = AND
R 的 n 次方 = 把 x 做右移 n 个 bit
S 的 n 次方 = 把 x 做循环右移 n 个 bit
函数的第五步骤
把[第四步骤]计算完成的A~H(t=63),分别再次加上 A~H 的初值。
比如:A63 = 0x00000001,A初值 = 0x6909e667
那么第五步骤就是(A63+A初值)= 0x6909e668
比如:B63 = 0x00000010,B初值 = 0xbb67ae85
那么第五步骤就是(B63+B初值)= 0xbb67ae95
若[消息]长度只有 55 bytes(含)以下,那么此时的A~H就是[摘要]。
若[消息]长度大于 55 bytes,那么此时的A~H就是下一区块(chunk)的 A~H初值。
各位大佬,一键三连!
点赞、留言、加关注!
本篇点赞破 1000 ,光速更新下一章。