開發者工具 · SHA 雜湊計算器
Hex、Base64 和原始位元組:編寫相同 SHA 摘要的三種方法
· 工作原理
sha-256 base64 編碼 檔案格式
sha256sum 列印十六進制,package-lock.json 儲存 base64,Docker 使用 sha256: 前綴。它們可以都是相同的 32 位元組。這篇文章解釋了每種表示形式以及如何在它們之間進行轉換。
看起來不同但相同的雜湊值 — 相同檔案的鎖定檔案字串和終端校驗和
SHA-256 摘要本質上是 32 位元組。您編寫這些位元組的方式決定了摘要的外觀。一個摘要,32 相同字節,顯示為 64 十六進位字元(每個位元組兩個),或 44 base64 字元(大約每三個位元組四個),或根據三個位元組顯示不同的長度和格式。之所以會出現混亂,是因為鎖定檔案可能顯示一種表示形式,而終端顯示另一種表示形式,兩者都針對相同的底層 32 位元組。
理解編碼是轉變「為什麼這些看起來不同?」的步驟。變成「我可以確認它們是相同的」。一旦將它們解碼回字節,所有三種表示形式都是等效的。
摘要是位元組 — 20、32、48 或 64,取決於演演算法,在任何文字編碼之前
在任何文字表示存在之前,結果是摘要位元組的 ArrayBuffer。 ToolAcre 使用 Uint8Array 包裝該緩衝區,然後將每個位元組寫入兩個十六進位數字,或在呼叫 btoa 之前將每個位元組轉換為二進位字元。兩個格式化程式都不會重新執行哈希,也不會更改單一摘要位元。
位元組寬度遵循此工具中選定的演演算法:SHA-1 傳回二十個位元組,SHA-256 三十二個位元組,SHA-384 四十八個位元組和SHA-512 六十四個位元組。這些是由演演算法元資料和測試驗證的支援輸出。原始位元組適合編程比較; hex 和 base64 是需要文字的通道的傳輸符號。
十六進制 — 每個位元組兩個字符,為什麼它在命令列工具中占主導地位,以及案例問題
十六進位表示使用數字 0-9 和字母 A-F(或 a-f)來表示 4 位元半位元組的 16 可能值。兩個十六進制數字代表一個位元組。輸入 abc 的 SHA-256 摘要為 32 位元組,因此它顯示為 64 十六進位字元:ba7816bf8f01cfea414140de5dae2223b0036bf這是大多數命令列工具列印的格式。十六進制是人類可讀且明確的;每個位元組每次都由完全相同的兩個字元表示。
十六進位是檔案和命令列中校驗和和雜湊的預設格式。它易於閱讀和複製,並沒有填充,解釋時不區分大小寫(儘管約定一致規定小寫或大寫),並沒有需要在 URL 或 JSON 中轉義的特殊字符。缺點是它需要的字元數是原始位元組的兩倍,這就是為什麼存在其他格式的原因。
Base64 和 base64url — 每三個位元組大約四個字元、填充以及每個字元出現的位置(SRI、npm、SSH 指紋)
Base64 將三個位元組編碼為從 64 個字元字母表中提取的四個字元:A-Z、a-z、0-9、+、/。三個位元組 61 62 63(abc 的 ASCII 代碼)在 base64 中編碼為 YWJj。完整的 32 位元組 SHA-256 摘要編碼為大約 44 個 Base64 字元。使用 = 字元進行填充會使輸出長度達到 4 的倍數,因此 44 個字元加上 0 填充(因為 32 是 3 的倍數,所以不需要填充)。解碼過程相反:四個 Base64 字元解碼為三個位元組。
Base64 出現在 package-lock.json 檔案、npm Shrinkwrap、HTML 中的 SRI(子資源完整性)屬性以及 SSH 金鑰指紋中。它很緊湊——比原始位元組長約 33%,而十六進位的長 100%。代價是並非所有文字表示都同樣易於閱讀。人眼看來,base64 看起來比十六進制更混亂。
前綴形式 — sha256:在容器摘要中,sha384- 在完整性屬性中,SHA256:在 SSH 中
Base64url 是 RFC 4648 中定義的變體,它將 - 和 _ 替換為 + 和 /. 字母變成 A-Z、a-z、0-9、-、__。 JWT 使用 base64url,因為 + 和 / 在 URL 中具有特殊意義(+ 可以讀取為查詢字串中的空格,/ 是路徑分隔符號)。 JWT 段始終是 base64url 編碼的,堅持使用標準 base64 的解碼器將拒絕它。相反,不接受標準字母表的 Base64url 解碼器將在標準 Base64 上失敗。
base64url 中的填充是可選的。標準 base64 填充 = 以確保輸出長度是 4 的倍數。 Base64url 通常會省略填充,因為 = 本身就是 URL 尷尬的。解碼器應該接受帶有或不帶有填充的 base64url,並編碼器應該明確其產生的內容。 ToolAcre base64 工具接受字母表並允許輸入中缺少填充,並允許您選擇輸出格式。
工作範例 — 摘要從十六進位轉換為 Base64 並轉換回來,並標記了位元組邊界
前綴形式將方案標識符新增至摘要。 Docker 映像摘要使用 sha256:ba7816bf...,其中 sha256: 是前綴。 SSH 指紋使用 SHA256:,有冒號。某些工具使用 sha256= 或 SHA256= (有等號)。前綴純粹是提供資訊的;它告訴您哪個演演算法產生了摘要。刪除前綴會在相同的編碼中留下相同的位元組。
比較摘要時,前綴是噪音。如果一個工具列印 SHA256:ba78... 而另一個工具列印 ba78...,則它們是相同的摘要;前綴只是有關格式的元資料。同樣,像 sha256:-(在某些容器上下文中使用)或 sha384-(在完整性屬性中使用)這樣的前綴是不更改位元組的格式約定。剝去它們進行比較。
這不包括什麼——給定工具發出哪種編碼;比較之前檢查輸出格式
輸入 abc 的 SHA-256 之一摘要以多種形式出現:十六進制(64 個字符)、帶填充的 base64(44 個字符)、帶填充的 base64url(44 個字符,用 - 和 _ 代替 + 和 /),或帶有各種前綴。要確認它們相同,請將每個解碼回位元組並比較位元組。十六進位表示形式 ba7816bf... 解碼為位元組 0xba 0x78 0x16 0xbf 0x8f 0x01 0xcf 0xea ... Base64 表示形式在解碼時轉換為相同的位元組序列。
ToolAcre SHA 雜湊計算器預設以十六進位輸出。如果需要 Base64,可以使用單獨的工具將十六進位轉換為 Base64,或使用同一網站上的 Base64 公用程式直接對文字進行編碼。為特定上下文設計的工具(npm 用於 package-lock.json,Docker 用於映像摘要)以其上下文期望的格式輸出。當工具在格式上不一致時,了解這些都是相同的 32 位元組,可以消除混亂。
重點:比較字節,而不是字串——使用 ToolAcre SHA 雜湊計算器計算摘要,然後轉換為您要檢查的表示形式
要將十六進位摘要手動轉換為 Base64,請將十六進位數字分組為位元組,將每個位元組轉換為十進制,然後使用 Base64 字母表進行編碼。位元組 0xba (十六進位 ba) 是十進位 186;0x78 是 120;0x16 是 22;0xbf 是 191。將這四個位元組分組並編碼為base64,得到字元w(字母中的0 + 22),as(編碼186),AA(編碼120),vw(編碼191)。完整的摘要需要執行 10 次,並在需要時進行填入。這個手動過程很有啟發性,但很乏味; Base64 轉換器工具使其變得即時。
關鍵的見解是摘要首先是字節,文字表示是其次的。相同位元組的每次編碼都會解碼回相同的字節,因此出於完整性驗證的目的可以互換。十六進位的大小寫差異、base64 的填滿差異、前綴和間距都是不會影響實際值的格式選擇。當您掌握了在表示形式之間進行轉換的能力時,摘要格式不匹配就成為您可以解決的調試問題,而不是謎團。