Md5
為什麼 md5_crypt 會移動字節?
前幾天我查看了 md5_crypt 的程式碼(是的,我知道它不安全),我注意到在將所有內容與奇怪的 md5 雜湊混合後,它會生成一個具有奇怪字節順序的 base64 字元串。您可以在 FreeBSD 實現的第 144-155 行或呼叫此函式的passlib中看到。
他們為什麼這樣做?
您應該考慮的候選答案之一是“沒有充分的理由”。正如 Provos 和 Mazières 在bcrypt USENIX 論文(第 6.1.2 節)中所說:
算法中的某些步驟讓人懷疑該方案是從密碼學的角度設計的——例如,密碼長度的二進製表示在某個點決定了哪些數據被散列,對於每個零位,密碼的第一個字節和對於每個設置位,前一個雜湊計算的第一個字節。
這是對算法的不同步驟的評論,但我懷疑它也可以概括為您突出顯示的步驟。任何一半體面的散列函式都會擴散其狀態,MD5 也不例外,因此對 MD5 輸出的位進行洗牌是值得懷疑的。
PHK 寫了一篇 md5crypt 的歷史,可能有助於我們了解他當時的心態,儘管它並沒有深入到具體細節,所以它並沒有特別說明問題的步驟。
據我所知,程式碼的目的是充當生成“安全”密碼雜湊的工具。我懷疑字節順序決定是任意的,並且不提供任何加密安全性。
許多分組密碼的設計在最後一輪省略了狀態轉置,因為它沒有提供任何額外的安全性來對抗攻擊者。
FreeBSD 程式碼行 144-155 如下:
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = final[11] ; strlcat(passwd, to64(l, 2), sizeof(passwd));
最後的字元串看起來有點像:
final[0] || final[6] || final[12] || final[1] || final[7] || final[13] || final[2] || final[8] || final[13] || final[3] || final[9] || final[14] || final[4] || final[10] || final[14] || final[5] || final[11] || final[16]
根據以下兩個 usenix 文章Traditional crypt , MD5 crypt看來,此程式碼的目的不是作為 MD5 的教科書實現,而是作為美國密碼出口禁令的解決方法,並作為 crypt 的更安全替代品。