sha256算法原理


1. SHA256簡介

SHA256是SHA-2下細分出的一種算法

SHA-2下又可再分為六個不同的算法標准

包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。

這些變體除了生成摘要的長度 、循環運行的次數等一些微小差異外,算法的基本結構是一致的。

回到SHA256上,說白了,它就是一個哈希函數。

哈希函數,又稱散列算法,是一種從任何一種數據中創建小的數字“指紋”的方法。散列函數把消息或數據壓縮成摘要,使得數據量變小,將數據的格式固定下來。該函數將數據打亂混合,重新創建一個叫做散列值(或哈希值)的指紋。散列值通常用一個短的隨機字母和數字組成的字符串來代表。

對於任意長度的消息,SHA256都會產生一個256bit長的哈希值,稱作消息摘要。

sha256在線驗證工具地址

2. SHA256原理詳解

2.1 常量初始化

SHA256算法中用到了8個哈希初值以及64個哈希常量

其中,SHA256算法的8個哈希初值如下:

h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

 

這些初值是對自然數中前8個質數(2,3,5,7,11,13,17,19)的平方根的小數部分取前32bit而來。

在SHA256算法中,用到的64個常量如下:

428a2f98 71374491 b5c0fbcf e9b5dba5
3956c25b 59f111f1 923f82a4 ab1c5ed5
d807aa98 12835b01 243185be 550c7dc3
72be5d74 80deb1fe 9bdc06a7 c19bf174
e49b69c1 efbe4786 0fc19dc6 240ca1cc
2de92c6f 4a7484aa 5cb0a9dc 76f988da
983e5152 a831c66d b00327c8 bf597fc7
c6e00bf3 d5a79147 06ca6351 14292967
27b70a85 2e1b2138 4d2c6dfc 53380d13
650a7354 766a0abb 81c2c92e 92722c85
a2bfe8a1 a81a664b c24b8b70 c76c51a3
d192e819 d6990624 f40e3585 106aa070
19a4c116 1e376c08 2748774c 34b0bcb5
391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3
748f82ee 78a5636f 84c87814 8cc70208
90befffa a4506ceb bef9a3f7 c67178f2

 

和8個哈希初值類似,這些常量是對自然數中前64個質數(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97…)的立方根的小數部分取前32bit而來。

2.2 信息預處理(pre-processing)

SHA256算法中的預處理就是在想要Hash的消息后面補充需要的信息,使整個消息滿足指定的結構。

信息的預處理分為兩個步驟:附加填充比特附加長度。

STEP1:附加填充比特

在報文末尾進行填充,使報文長度在對512取模以后的余數是448

填充是這樣進行的:先補第一個比特為1,然后都補0,直到長度滿足對512取模后余數是448。

需要注意的是,信息必須進行填充,也就是說,即使長度已經滿足對512取模后余數是448,補位也必須要進行,這時要填充512個比特。

因此,填充是至少補一位,最多補512位。

例:以信息“abc”為例顯示補位的過程。

a,b,c對應的ASCII碼分別是97,98,99

於是原始信息的二進制編碼為:01100001 01100010 01100011

補位第一步,首先補一個“1” : 0110000101100010 01100011 1

補位第二步,補423個“0”:01100001 01100010 01100011 10000000 00000000 … 00000000

補位完成后的數據如下(為了簡介用16進制表示):

61626380 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000

 

為什么是448?

因為在第一步的預處理后,第二步會再附加上一個64bit的數據,用來表示原始報文的長度信息。而448+64=512,正好拼成了一個完整的結構。

STEP2:附加長度值

附加長度值就是將原始數據(第一步填充前的消息)的長度信息補到已經進行了填充操作的消息后面

wiki百科中給出的原文是:append length of message (before pre-processing), in bits, as 64-bit big-endian integer

SHA256用一個64位的數據來表示原始消息的長度。

因此,通過SHA256計算的消息長度必須要小於$ 2^64 $,當然絕大多數情況這足夠大了。

長度信息的編碼方式為64-bit big-endian integer

關於Big endian的含義,文末給出了補充

回到剛剛的例子,消息“abc”,3個字符,占用24個bit

因此,在進行了補長度的操作以后,整個消息就變成下面這樣了(16進制格式)

61626380 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000018

 2.3 邏輯運算

邏輯運算 含義
∧ \land 按位“與”
¬¬ \neg ¬ 按位“補”
⊕ \oplus 按位“異或”
SnSn S^{n} Sn 循環右移n個bit
RnRn R^{n} Rn 右移n個bit

2.4 計算消息摘要

現在來介紹SHA256算法的主體部分,即消息摘要是如何計算的。

首先:將消息分解成512-bit大小的塊

 

 

假設消息M可以被分解為n個塊,於是整個算法需要做的就是完成n次迭代,n次迭代的結果就是最終的哈希值,即256bit的數字摘要。

一個256-bit的摘要的初始值H0,經過第一個數據塊進行運算,得到H1,即完成了第一次迭代

H1經過第二個數據塊得到H2,……,依次處理,最后得到Hn,Hn即為最終的256-bit消息摘要

圖中256-bit的Hi被描述8個小塊,這是因為SHA256算法中的最小運算單元稱為“字”(Word),一個字是32位。

此外,第一次迭代中,映射的初值設置為前面介紹的8個哈希初值,如下圖所示:

 

下面開始介紹每一次迭代的內容

STEP1:構造64個字(word)

對於每一塊,將塊分解為16個32-bit的big-endian的字,記為w[0], …, w[15]

也就是說,前16個字直接由消息的第i個塊分解得到

其余的字由如下迭代公式得到:

 

STEP2:進行64次循環

3.算法偽代碼​

Note: All variables are unsigned 32 bits and wrap modulo 232 when calculating


Initialize variables
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19


Initialize table of round constants
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=
   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2


Pre-processing:
append the bit '1' to the message
append k bits '0', where k is the minimum number >= 0 such that the resulting message
    length (in bits) is congruent to 448(mod 512)
append length of message (before pre-processing), in bits, as 64-bit big-endian integer


Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
    break chunk into sixteen 32-bit big-endian words w[0..15]

    Extend the sixteen 32-bit words into sixty-four 32-bit words:
    for i from 16 to 63
        s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor(w[i-15] rightshift 3)
        s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor(w[i-2] rightshift 10)
        w[i] := w[i-16] + s0 + w[i-7] + s1

    Initialize hash value for this chunk:
    a := h0
    b := h1
    c := h2
    d := h3
    e := h4
    f := h5
    g := h6
    h := h7

    Main loop:
    for i from 0 to 63
        s0 := (a rightrotate 2) xor (a rightrotate 13) xor(a rightrotate 22)
        maj := (a and b) xor (a and c) xor(b and c)
        t2 := s0 + maj
        s1 := (e rightrotate 6) xor (e rightrotate 11) xor(e rightrotate 25)
        ch := (e and f) xor ((not e) and g)
        t1 := h + s1 + ch + k[i] + w[i]
        h := g
        g := f
        f := e
        e := d + t1
        d := c
        c := b
        b := a
        a := t1 + t2

    Add this chunk's hash to result so far:
    h0 := h0 + a
    h1 := h1 + b
    h2 := h2 + c
    h3 := h3 + d
    h4 := h4 + e
    h5 := h5 + f
    h6 := h6 + g
    h7 := h7 + h

Produce the final hash value (big-endian):
digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM