SHA演算法描述及實現
SHA 演算法的原理及實現
章節目錄
- 簡介
-
演算法描述
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 - 實現
<b>作者能力有限, 如果您在閱讀過程中發現任何錯誤, 還請您務必聯絡本人,指出錯誤, 避免後來讀者再學習錯誤的知識.謝謝!</b>
簡介
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 演算法的計算步驟從大體上可以分為兩步: <b>資料準備</b> 和 <b>Hash 計算</b>.
資料準備
在資料準備階段, 我們也像 MD5 那樣, 需要先將資料填充到特定長度,同時將原始資料長度填充進去,然後對資料進行分塊, 因為我們的演算法是基於塊進行的. SHA 家族中的具體演算法的實現大體相同, 只是填充長度的bit數,分塊大小略有不同而已.
在資料準備階段我們需要進行三個操作: 資料填充, 資料分塊, 設定初始 Hash 值.
資料填充
我們使用
表示資料資料, 它的長度使用
表示.
對於演算法 <b>SHA-1</b>, <b>SHA-224</b>, <b>SHA-256</b>, 資料填充方法如下:
先填充 1 bit 的 '1' 到資料末尾, 然後緊接著填充 k 個 '0', 這裡 k 需要時最小的非負數且滿足, 也即是說需要將原始資料長度填充到<b>差64位就是512的整數倍</b>.
上述操作結束後, 將表示為 64 bit 的bit陣列填充到上述步驟所得的資料之後, 此時我們得到一個長度為512整數倍的資料.
舉個例子:
假設我們的資料資料為"abc", 它的長度為24(bit). 我們通過計算得到 k 應該是 423(448 - 1 - 24). 此時填充之後的資料應該如下:
填充完成之後的長度是512(bit).
對於演算法 <b>SHA-384</b>, <b>SHA-512</b>, <b>SHA-512/224</b>, <b>SHA-512/256</b>, 資料填充方法如下:
先填充 1 bit 的 '1' 到資料末尾, 然後緊接著填充 k 個 '0', 這裡 k 需要時最小的非負數且滿足, 也即是說需要將原始資料長度填充到<b>差128位就是1024的整數倍</b>.
上述操作結束後, 將表示為 128 bit 的bit陣列填充到上述步驟所得的資料之後, 此時我們得到一個長度為1024整數倍的資料.
以上述的例子為例:
假設我們的資料資料為"abc", 它的長度為24(bit). 我們通過計算得到 k 應該是 871(896 - 1 - 24). 此時填充之後的資料應該如下:
填充完成之後的長度是1024(bit).
資料分塊
填充後的資料需要被分塊.
對於演算法 <b>SHA-1</b>, <b>SHA-224</b>, <b>SHA-256</b>,
我們將資料分為個 521-bit 的塊, 分別表示為
512-bit 的塊又可以被劃分為 16 個字(32-bit Word), 分別表示為
對於演算法 <b>SHA-384</b>, <b>SHA-512</b>, <b>SHA-512/224</b>, <b>SHA-512/256</b>
我們將資料分為個 1024-bit 的塊, 分別表示為
1024-bit 的塊又可以被劃分為 16 個字(64-bit Word), 分別表示為
設定初始 Hash 值
每個特定的 SHA 演算法, 都有相應的初始 Hash 值. 在計算 Hash 之前, 我們需要先將初始值準備好.
為了減少文章篇幅, 這裡我們不列出這些初始值和 Hash 計算過程中使用到的常量
,後邊演算法實現中會給出相應資料.
Hash 計算
SHA-1
SHA-1 演算法要求輸入資料的長度不能大於
, 最小長度為0.
虛擬碼如下:
=
For i=1 to N:
{
//1. 計算//2. 初始化工作變數 a, b, c, d, e. 他們用來儲存在第 i-1 次迭代式的 Hash 值
// 他們的初始值就是我們在"設定初始 Hash 值"小節中所說的值.
// 3
For t=0 to 79:
{
}
//4. 計算第
中間 hash 值
}
在經過 N 次迭代之後, 最終結果為
的位元組表示依次連線所組成的位元組陣列.
SHA-256
SHA-256 演算法要求輸入資料的長度不能大於
, 最小長度為0.
SHA-224 演算法的計算過程與 SHA-256 相同, 卻別在於使用的初始化 Hash 值不同, 且 SHA-224 演算法的最終結果是取 SHA-256 演算法結果的前 224 bit.
虛擬碼如下:
For i=1 to N:
{
//1. 計算//2. 初始化工作變數 a, b, c, d, e, f, g, h. 他們用來儲存在第 i-1 次迭代式的 Hash 值
// 他們的初始值就是我們在"設定初始 Hash 值"小節中所說的值.
// 3
For t=0 to 63:
{
}
//4. 計算第
中間 hash 值
}
在經過 N 次迭代之後, 最終結果為
的位元組表示依次連線所組成的位元組陣列.
SHA-512
SHA-512 演算法要求輸入資料的長度不能大於
, 最小長度為0.
SHA-384 演算法的計算過程與 SHA-512 相同, 卻別在於使用的初始化 Hash 值不同, 且 SHA-384 演算法的最終結果是取 SHA-512 演算法結果的前 384 bit.
SHA-512/224 演算法的計算過程與 SHA-512 相同, 卻別在於使用的初始化 Hash 值不同, 且 SHA-512/224 演算法的最終結果是取 SHA-512 演算法結果的前 224 bit.
SHA-512/256 演算法的計算過程與 SHA-512 相同, 卻別在於使用的初始化 Hash 值不同, 且 SHA-512/256 演算法的最終結果是取 SHA-512 演算法結果的前 256 bit.
虛擬碼如下:
For i=1 to N:
{
//1. 計算//2. 初始化工作變數 a, b, c, d, e, f, g, h. 他們用來儲存在第 i-1 次迭代式的 Hash 值
// 他們的初始值就是我們在"設定初始 Hash 值"小節中所說的值.
// 3
For t=0 to 79:
{
}
//4. 計算第
中間 hash 值
}
在經過 N 次迭代之後, 最終結果為
的位元組表示依次連線所組成的位元組陣列.
演算法實現
本人使用 go 語言實現了該演算法. github:https://github.com/UselezzProgrammer/mycrypto
END!