開發者工具 · SHA 雜湊計算器
SHA-256 逐步:填入、訊息排程與 64 回合
· 工作原理
sha-256 密碼學 瀏覽器 API JavaScript
SHA-256 填入您的輸入,將其分割為 512 位元區塊,並透過 64 輪混合執行每個區塊。這篇文章用簡單的語言解釋了每個階段,不需要密碼學背景。
你的位元組到底發生了什麼事——大多數開發人員從未打開過的黑盒子
SHA-256 是一種確定性演演算法,可將任何輸入轉換為 256 位元(32 位元組)指紋。從外面看起來像一個黑盒子,實際上是一系列明確定義的步驟。了解這些步驟可以消除神秘感,讓您驗證正確性、追蹤錯誤並了解輸出為何如此。演演算法的每一個部分都是公開的;力量來自於設計,而不是來自於保密。
此演演算法在 512 位元區塊上運作。如果您的輸入較短,則會填入。如果它更長,它會被分成多個區塊,每個區塊按順序處理,每個區塊的輸出輸入到下一個區塊。處理完所有區塊後,您將獲得八個 32 位數字,它們連接在一起形成最終的 256 位摘要。
填入 — 附加 1 位元、零和 64 位元訊息長度以達到 512 位元的倍數
填充步驟是確定性和形式化的。在實際輸入之後,附加一個 1 位元(實際上,如果您的輸入在位元組邊界上結束,則附加位元組 0x80)。然後附加零位,直到 64 位少於 512 位的倍數。最後,附加輸入長度的 64 位元大端編碼(以位元為單位)。此填充可確保每個訊息都是 512 位元的倍數,並對原始長度進行編碼,因此不同長度的相同輸入不能產生相同的摘要。
對於輸入 abc(3 位元組 = 24 位元),填入訊息為 512 位元(一個區塊):三個位元組 61 62 63,後面跟著 0x80,後面跟著零,再後面跟著 24 的 64 位元編碼(在 64 位元大端欄位中為 0x00...0x18)。该消息現在正好填滿一個 512 位塊。對於空字串,填入會附加 0x80,後面跟著零,最後是 0x00...0x00(表示輸入的 0 位元)。對於較長的輸入(例如 100 位元組檔案),填入會將最後一個區塊填入 512 位,並指示原始長度的 800 位。
初始值和常數由演演算法固定;它們的歷史推導是在儲存庫證據之外
此演演算法以八個 32 位元工作變數開始,初始化為前八個質數平方根的小數部分的前 32 位元。這些是硬編碼常數,在任何參考實作和加密庫的原始程式碼中都可見。它們的存在是因為使用數學中的固定常數可以避免對隱藏後門的懷疑。 ToolAcre 工具使用瀏覽器的 Web Crypto 實現,該實作應用了這些相同的常數。
此演演算法也使用 64 捨去常數,這些常數源自前 64 質數的立方根的小數部分的前 32 位。這些也是固定的和公開的。這些常數充當附加的混合材料;改變它們會破壞演演算法並產生不同的摘要。
訊息調度 — 透過移位和輪換將 16 字擴展為 64
訊息調度透過特定公式將 16 字(512 位元)擴展為 64 字(2048 位元)。對於 0-15 輪,單字直接來自輸入區塊。對於 16-63 輪,每個新單字是透過採用兩個較早的單字(在特定偏移處)、應用旋轉和移位、在另一個單字中進行異或並儲存結果來計算的。這個公式在一個區塊的上下文中是確定性且可逆的,但擴充將輸入的影響分散到所有 64 輪中。
擴展公式使用右旋轉(一種循環位移位,其中從一端掉落的位元重新出現在另一端)和右移操作。旋轉保留所有位元但改變它們的位置;右移會丟棄位元。旋轉、移位和異或運算的組合確保輸入的每一位都會影響調度中的多個字。
一輪 — Ch、Maj 和 Sigma 函數被描述為位元混合操作,以及八個工作變數如何更新
每一輪 64 處理訊息調度的一個字並更新八個工作變數。核心函數涉及六個操作:基於控制變數選擇位元的條件混合(通常稱為 Ch,表示「選擇」)、選擇三個變數中最常見值的多數函數 (Maj)、旋轉和移位工作變數的兩個特殊混合函數(Sigma_0 和 Sigma_1)以及對 2^32 取模的加法。所有算術都是在 32 位元字上完成的,因此溢出會迴繞。
「選擇」函數採用三個 32 位元輸入,並對於每個位元位置,如果控制位元為 1,則從第一個輸入中選擇位元;如果控制位元為 0,則從第二個輸入中選擇位元。多數函數查看三個輸入,並針對每個位元位置輸出這三個輸入中最常出現的位元值。這些是非線性操作,它們打破了線性並確保微小的輸入變化在狀態中不可預測地傳播。
連結區塊並產生輸出 - 將每個區塊的結果加入到執行狀態中
每輪都會透過旋轉所有八個工作變數並合併根據當前輪常數、訊息調度字和先前狀態計算的新值來更新所有八個工作變數。前七個工作變數發生變化:第 8 個變為第 1 個,第 1 個變為第 2 個,依此類推。新的第八個值是使用混合函數根據舊變數計算得出的。經過 64 輪後,您將獲得八個新的 32 位元值。這些被加入(模 2^32)到初始常數,產生該區塊的最終雜湊狀態。
對於多區塊訊息,一個區塊中的八個值將成為下一個區塊的初始狀態。此鏈確保輸入中任何位置的變更都會影響所有後續區塊。當到達最後一個區塊時,輸入的每一位都會影響最終的輸出。
工作範例以及未涵蓋的內容 - 追蹤簡訊的填充和區塊計數;安全證明超出範圍
對於輸入 abc,訊息在填入後適合一個 512 位元區塊。填充添加了 424 位,總共 512 位。訊息調度將其擴展為 64 個字。每輪消耗一個字並透過混合函數更新八個工作變數。經過 64 輪後,狀態與初始常數進行異或,產生最終摘要 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad。
這是一個已發佈的測試向量:對相同輸入進行相同的計算總是會產生相同的輸出。 ToolAcre 工具透過瀏覽器的 Web Crypto 實作執行此精確計算。您可以透過對 abc 進行雜湊並將結果與已知向量進行比較來驗證它。任何正確實作 Web Crypto 的瀏覽器都會產生相同的輸出;演演算法不允許任何捷徑或替代路徑。
重點:Web 加密執行確定性 SHA-256 混合而不暴露秘密
該演演算法是公開的,並每一步都是確定性的。混合函數(Ch、Maj、Sigma_0、Sigma_1)被選為非線性的,這意味著更改一個輸入位元不會如預期地改變一個輸出位元。將 16 訊息字擴展到 64 確保整個輸入影響整個計算。 64 輪次和狀態連結意味著輸出對輸入的每一位都很敏感,並儲存庫使用結果輸出作為確定性摘要。抗碰撞性是一種有限制的安全屬性,而不是保證重複輸出在數學上是不可能的。
密碼證明超出了本文的範圍。關鍵是您現在知道演演算法實際上是做什麼的。它不是魔法,也不是黑盒子。如果您想驗證 ToolAcre 是否正確進行雜湊處理,請透過這些步驟追蹤您自己的輸入,或使用其他語言的參考實作並比較結果。瀏覽器的實作和任何正確的引用都會為相同的輸入產生相同的摘要。