SHA-256 是一種單向加密摘要,可將任何不超過瀏覽器工具上限的輸入對應到一個固定的 256 位元 (32 位元組) 值,以 64 個小寫十六進位字元或 44 字元含填補字元的 Base64 表示。該摘要是確定性的:相同的位元組序列必定產生相同的摘要,即使只有一個位元組改變,也大約會改變輸出位元的一半。SHA-256 屬於 SHA-2 家族,該家族在 NIST FIPS 180-4 中被標準化,規範中規定了訊息如何填補、如何分割成 512 位元的區塊、如何展開成 64 字排程,以及如何折疊成八個 32 位元的工作值,這些工作值最終成為摘要的最後八個字。因此,產生 SHA-256 雜湊值就是將精確的位元組餵入這個標準化程序,並以另一個系統可用來比對的格式記錄所產生的 32 位元組值。兩種輸出格式描述的都是同一組 32 個位元組:十六進位形式使用字元 0-9 和 a-f,而 Base64 形式則使用標準 RFC 4648 字元集並以 = 填補。改變十六進位形式的字母大小寫(例如將 A1B2 呈現為 a1b2)只會改變呈現方式,絕不會改變底層的摘要位元組。在儲存任何摘要時一併記錄演算法名稱非常重要,因為 64 字元的 SHA-256 值在外觀上無法與截斷的 SHA-512,或與未記載的校驗和格式區分開來。

generate sha256 hash
產生 SHA256 雜湊值並與參考值進行比對

「產生 SHA-256 雜湊值」實際上會產生什麼

輸出結果是指紋,而不是輸入內容的加密副本。沒有金鑰、沒有支援的反向運算,也沒有內建機制可以證明是誰產生了輸入內容。這個指紋對於空字串和 100 MB 的檔案具有完全相同的長度,這正是它作為精簡參考值的用處,讓第二個系統可以重新計算並進行比對。當你產生 SHA-256 雜湊值時,你就是承諾採用某一特定的位元組序列 —— 文字模式輸入的精確 UTF-8 位元組,或檔案模式輸入中包含檔頭和行尾符號在內的每一個位元組 —— 並記錄其確定性的輸出。

正是這種確定性讓驗證得以運作。如果雙方約定好哪些位元組應該產生什麼摘要,那麼任何重新計算摘要並看到相符結果的第三方,就有強力的證據證明這些位元組是相同的。如果兩個摘要即使相差一個位元,位元組在某處必定不同。

何時適合產生 SHA-256 雜湊值

SHA-256 的標準使用情境是位元組層級的完整性檢查:比對下載的檔案與廠商發布的摘要、確認兩個產物是相同的複本,或是產生建置與部署工作流程所需的值。這三者都依賴同一個特性 —— 相同的位元組產生相同的摘要。

SHA-256 在三種常見情境中是錯誤的選擇。第一,當你需要兩個共享密鑰的系統之間進行訊息驗證時,請改用 HMAC-SHA-256,因為普通摘要不需要金鑰就能重新計算。第二,當你需要用公開金鑰建立來源證明時,請使用數位簽章,因為雜湊識別的是位元組而非作者。第三,在儲存密碼時,不要直接套用 SHA-256:它的速度雖然有利於完整性檢查,但同樣也讓攻擊者更容易測試猜測。帳號系統應使用唯一 salt 加上專為密碼設計、且經過記憶體與時間成本校調的雜湊函式。

目標合適的基元為何單獨使用 SHA-256 不足
確認下載的檔案完整無缺SHA-256 摘要無 —— 位元組相同,摘要相同
在共享密鑰的兩方之間驗證訊息HMAC-SHA-256普通摘要不需要金鑰就能重新計算
證明文件是由特定金鑰持有者所簽署數位簽章雜湊識別的是位元組,不是作者
儲存使用者密碼搭配 salt 的 Argon2、scrypt 或 bcrypt原始的 SHA-256 對抗攻擊者儲存來說太快了

如何產生 SHA-256 雜湊值

SHA256 雜湊產生器完全在目前的瀏覽器分頁中執行標準的 FIPS 180-4 摘要運算,因此你所選取的位元組從不離開裝置。下列步驟同時適用於文字與檔案輸入。

  1. 選擇文字或檔案輸入。文字方面,請輸入或貼上要驗證的確切字串;檔案方面,請從本機磁碟選擇最多 100 MB 的位元組。
  2. 確認輸入編碼。文字模式會在雜湊前將字串編碼為 UTF-8,而顯示的位元組數也是結果脈絡的一部分 —— 帶有變音符號的字母、表情符號,以及 ASCII 之外的文字,都可能各佔用多個位元組。
  3. 產生摘要。瀏覽器會委派給標準的 SHA-256 實作,產生 32 個結果位元組。
  4. 複製另一個系統所預期的格式:一般下載與套件管理員使用 64 字元的小寫十六進位,而以該字元集儲存雜湊值的系統則使用含填補字元的 Base64。
  5. 比對完整的輸出結果,而非前綴。截斷相符並不算相符。

不論你是在驗證單一字串還是整個安裝檔,同樣的三個步驟 —— 選擇、產生、複製 —— 都適用。若需要專門針對文字輸入的逐步指引,請參閱有關以正確方式產生字串的 SHA-256 雜湊值的教學。

將你的摘要與參考值進行比對

驗證是比對問題,而不是產生問題。一旦你取得摘要,請透過經驗證的管道取得預期值 —— 廠商的 HTTPS 網站、已簽署的發布清單,或是與下載檔案一同發布的校驗和檔案 —— 並比對輸出的每一個字元。許多已發布的校驗和是以十六進位撰寫;有些建置系統要求 Base64;請選用參考值所使用的表示方式,避免因大小寫或字元集差異被誤判為不相符。

空位元組字串是有效的輸入,其標準 SHA-256 摘要以 e3b0c442 開頭。這個固定輸出對於任何宣稱實作 SHA-256 的工具來說,都是一個有用的健全性檢查:如果貼上空值卻產生不同的摘要,該工具就沒有正確實作此標準。來自 NIST FIPS 180-4 的獨立測試向量涵蓋了空字串與較長的訊息,而密碼學演算法驗證計畫則在 NIST CAVP Secure Hashing 頁面維護跨實作的測試資料。

為何相符的雜湊值並非總是值得信任

相符的雜湊值只能證明兩個位元組序列相同,並不能證明其中任何一個序列就是你預期的內容。如果攻擊者能同時置換下載的檔案和旁邊顯示的校驗和,那麼重新計算 SHA-256 也會忠實地確認攻擊者的這一對。這就是為什麼預期摘要的來源與摘要本身同樣重要。

只有在參考摘要是透過符合風險等級的經驗證管道傳遞時,才能信任它:廠商自有網域上的 HTTPS 頁面、你能驗證其簽章的已簽署發布清單、由發行維護者簽署的套件中所內嵌的校驗和,或是任何能偵測出竄改的其他管道。發佈在第三方論壇或未經驗證電子郵件中的校驗和,即使位元組剛好相符,也不算經驗證的參考值。

雜湊值與參考值不相符的常見原因

大多數的不相符都是位元組層級的差異,而不是演算法的差異。在斷定工具有誤之前,請先逐一檢查下列項目。

  • 隱藏的換行字元。像是 echo "text" 這類 shell 指令通常會附加一個換行字元;"text\n" 的標準 SHA-256 與 "text" 的 SHA-256 並不相同。
  • 文字編碼不符。瀏覽器工具會對輸入字串的精確 UTF-8 位元組進行雜湊。如果參考值是基於包含非 ASCII 字元的 Windows-1252 或 Latin-1 字串計算出來的,兩者的結果就會不同。
  • Unicode 正規化形式不同。同一段可見文字可能以不同的 Unicode 正規化形式 (NFC、NFD、NFKC、NFKD) 編碼,即使字元看起來相同,位元組序列仍然不同。
  • 空格、Tab 與行尾位元組。尾端空格、Tab 字元,以及 CR 與 LF 行尾,都是會改變摘要的真實位元組。
  • 文字與檔案模式不符。如果你將檔案內容貼到文字模式中,任何位元組順序標記 (BOM) 以及編輯器所套用的任何行尾轉換都會遺失。若要與檔案層級的參考值比對,請直接對檔案進行雜湊。

對於超過 100 MB 的檔案,瀏覽器工具的摘要介面會接收完整的位元組緩衝區而非串流,因此設定此上限是為了保持分頁的響應能力。若要對數 GB 級的產物計算摘要而不耗盡瀏覽器記憶體,請使用本機上可信的串流工具 —— Linux 與 macOS 上的 sha256sum,或 Windows 上的 Get-FileHash。瀏覽器工具中的非同步工作識別也能防止較舊的檔案讀取或雜湊值取代較新的選取,因此即使在大檔案上遇到慢速磁碟,也不會悄悄換成過時的結果。

如果你正在權衡各種選項,HMAC SHA-512 雜湊產生器:原始與金鑰化摘要工作流程對此有詳細說明。