SHA 算法描述与实现

本文详细介绍了SHA算法家族,包括SHA-1, SHA-256和SHA-512的原理和实现步骤。内容涵盖了数据填充、数据分块和初始Hash值设置等关键环节,并提供了算法的计算过程概述。此外,还提及了SHA-224, SHA-384, SHA-512/224和SHA-512/256的区别。文章最后提到了作者的Go语言实现。" 123187366,5609386,UDP组播问题与解决方案,"['网络协议', 'UDP', '组播']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    SHA 算法的原理及实现

章节目录

  1. 简介
  2. 算法描述
    2.1 数据准备
    2.1.1 数据填充
    2.1.2 数据分块
    2.1.3 设置初始 Hash 值
    2.2 Hash 计算
    2.2.1 SHA-1
    2.2.2 SHA-256
    2.2.3 SHA-512
  3. 实现

作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢!

简介##

SHA 算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

本文我们将介绍以下 SHA 算法: SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256.

其中 SHA-224 和 SHA-256 使用相同的算法, 区别在于初始 Hash 值不同, 最终结果只使用算法输出的数据中的前224/256 bit.
SHA-384, SHA-512, SHA-512/224, SHA-512/256 使用相同的算法, 区别在于初始 Hash 值不同, 最终结果只使用算法输出的数据中的前384/512/224/256 bit.
而 SHA-2* 和 SHA-384,SHA-5* 算法也非常类似, 区别在于采用的字(Word) 长度不同, SHA-2*使用 32-bit 的字, 而 其他算法使用 64-bit 的字. 算法的迭代次数也不一样.

算法描述##

本文中将介绍的 SHA 算法的计算步骤从大体上可以分为两步: 数据准备Hash 计算.

数据准备###

在数据准备阶段, 我们也像 MD5 那样, 需要先将数据填充到特定长度,同时将原始数据长度填充进去,然后对数据进行分块, 因为我们的算法是基于块进行的. SHA 家族中的具体算法的实现大体相同, 只是填充长度的bit数,分块大小略有不同而已.

在数据准备阶段我们需要进行三个操作: 数据填充, 数据分块, 设置初始 Hash 值.

数据填充####

我们使用 M M M 表示数据数据, 它的长度使用 l l l 表示.

对于算法 SHA-1, SHA-224, SHA-256, 数据填充方法如下:
先填充 1 bit 的 ‘1’ 到数据末尾, 然后紧接着填充 k 个 ‘0’, 这里 k 需要时最小的非负数且满足 l + 1 + k ≡ 448 m o d 512 l+1+k\equiv448mod512 l+1+k448mod512, 也即是说需要将原始数据长度填充到差64位就是512的整数倍.
上述操作结束后, 将 l l l 表示为 64 bit 的bit数组填充到上述步骤所得的数据之后, 此时我们得到一个长度为512整数倍的数据.

举个例子:
假设我们的数据数据为"abc", 它的长度为24(bit). 我们通过计算得到 k 应该是 423(448 - 1 - 24). 此时填充之后的数据应该如下:
01100001 ⎵ a 01100010 ⎵ b 01100011 ⎵ c 1 00...00 ⏞ 423 00...0 11000 ⎵ t = 24 ⏞ 64 \underbrace{01100001}_{a}\quad \underbrace{01100010}_{b}\quad \underbrace{01100011}_{c}\quad 1 \quad \overbrace{00...00}^{423}\quad \overbrace{00...0\underbrace{11000}_{t=24}}^{64} a 01100001b 01100010c 01100011100...00 42300...0t=24 11000 64
填充完成之后的长度是512(bit).

对于算法 SHA-384, SHA-512, SHA-512/224, SHA-512/256, 数据填充方法如下:
先填充 1 bit 的 ‘1’ 到数据末尾, 然后紧接着填充 k 个 ‘0’, 这里 k 需要时最小的非负数且满足 l + 1 + k ≡ 896 m o d 1024 l+1+k\equiv896mod1024 l+1+k896mod1024, 也即是说需要将原始数据长度填充到差128位就是1024的整数倍.
上述操作结束后, 将 l l l 表示为 128 bit 的bit数组填充到上述步骤所得的数据之后, 此时我们得到一个长度为1024整数倍的数据.

以上述的例子为例:
假设我们的数据数据为"abc", 它的长度为24(bit). 我们通过计算得到 k 应该是 871(896 - 1 - 24). 此时填充之后的数据应该如下:
01100001 ⎵ a 01100010 ⎵ b 01100011 ⎵ c 1 00...00 ⏞ 871 00...0 11000 ⎵ t = 24 ⏞ 128 \underbrace{01100001}_{a}\quad \underbrace{01100010}_{b}\quad \underbrace{01100011}_{c}\quad 1 \quad \overbrace{00...00}^{871}\quad \overbrace{00...0\underbrace{11000}_{t=24}}^{128} a 01100001b 01100010c 01100011100...00 87100...0t=24 11000 128
填充完成之后的长度是1024(bit).

数据分块####

填充后的数据需要被分块.

对于算法 SHA-1, SHA-224, SHA-256,
我们将数据分为 N N N 个 521-bit 的块, 分别表示为
M ( 1 ) , M ( 2 ) , . . . , M ( N ) M^{(1)}, M^{(2)}, ..., M^{(N)} M(1),M(2),...,M(N)
512-bit 的块又可以被划分为 16 个字(32-bit Word), 分别表示为
M 0 ( i ) , M 1 ( i ) , . . . , M 15 ( i ) M^{(i)}_{0}, M^{(i)}_{1}, ..., M^{(i)}_{15} M0(i),M1(i),...,M15(i)

对于算法 SHA-384, SHA-512, SHA-512/224, SHA-512/256
我们将数据分为 N N N 个 1024-bit 的块, 分别表示为
M ( 1 ) , M ( 2 ) , . . . , M ( N ) M^{(1)}, M^{(2)}, ..., M^{(N)} M(1),M(2),...,M(N)
1024-bit 的块又可以被划分为 16 个字(64-bit Word), 分别表示为
M 0 ( i ) , M 1 ( i ) , . . . , M 15 ( i ) M^{(i)}_{0}, M^{(i)}_{1}, ..., M^{(i)}_{15} M0(i),M1(i),...,M15(i)

设置初始 Hash 值####

每个特定的 SHA 算法, 都有相应的初始 Hash 值. 在计算 Hash 之前, 我们需要先将初始值准备好.

为了减少文章篇幅, 这里我们不列出这些初始值和 Hash 计算过程中使用到的常量 K K K,后边算法实现中会给出相应数据.

Hash 计算###

SHA-1####

SHA-1 算法要求输入数据的长度不能大于 2 6 4 2^64 264, 最小长度为0.

伪代码如下:

R O T L n ( x ) = ( x &lt; &lt; n ) ∪ ( x &gt; &gt; w − n ) ROTL^n(x)=(x &lt;&lt; n) \cup (x &gt;&gt; w - n) ROTLn(x)=(x<<n)(x>>wn)

f t ( x , y , z ) f_t(x,y,z) ft(x,y,z) = { C h ( x , y , z ) = ( x ∩ y ) ⨁ ( ¬ x ∩ z ) , 0 ≤ t ≤ 19 P a r i t y ( x , y , z ) = x ⨁ y ⨁ z , 20 ≤ t ≤ 39 M a j ( x , y , z ) = ( x ∩ y ) ⨁ ( x ∩ z ) ⨁ ( y ∩ z ) , 40 ≤ t ≤ 59 P a r i t y ( x , y , z ) = x ⨁ y ⨁ z , 60 ≤ t ≤ 79 \begin{cases} Ch(x,y,z)=(x\cap y)\bigoplus (¬x\cap z), \qquad 0\leq t\leq19\\ \quad \\ Parity(x,y,z)=x\bigoplus y\bigoplus z, \qquad 20\leq t\leq39\\ \quad \\ Maj(x,y,z)=(x\cap y)\bigoplus (x\cap z)\bigoplus (y\cap z), \qquad 40\leq t\leq59\\ \quad \\ Parity(x,y,z)=x\bigoplus y\bigoplus z, \qquad 60\leq t\leq79\\ \quad \\ \end{cases} <

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值