為什麼 PyCrypto 和 M2Crypto 不在這裡產生與 OpenSSL 相同的結果(AES-128 ECB)
如果我執行以下命令,對於 openSSL:
echo -n "0123456789abcdef0123456789abcdef" | openssl aes-128-ecb -nosalt -nopad | xxd
並輸入密鑰“YELLOW SUBMARINE”,我得到以下密文:
a2a5 8316 129f c596 8341 c78a 0c36 5d20 a2a5 8316 129f c596 8341 c78a 0c36 5d20
然而在 PyCrypto 中,以下程式碼:
from Crypto.Cipher import AES key = b'YELLOW SUBMARINE' cipher = AES.new(key, AES.MODE_ECB, "") msg = cipher.encrypt(b'0123456789abcdef0123456789abcdef')
輸出:
20 1e 80 2f 7b 6a ce 6f 6c d0 a7 43 ba 78 ae ad 20 1e 80 2f 7b 6a ce 6f 6c d0 a7 43 ba 78 ae ad
(為清楚起見添加了換行符)
這種差異的原因是什麼?兩者都是 ECB 模式下的 128 位 AES。PyCrypto 似乎沒有加鹽,在這種明文的任何情況下都不需要填充。
PS 同樣的事情發生在 M2Crypto 上:
import M2Crypto cipher=M2Crypto.EVP.Cipher('aes_128_ecb',b'YELLOW SUBMARINE',"", op=1, padding=0, salt=None) out=b'' plaintext=b'0123456789abcdef0123456789abcdef' out=out+cipher.update(plaintext) print ' '.join(x.encode('hex') for x in out)
輸出:
20 1e 80 2f 7b 6a ce 6f 6c d0 a7 43 ba 78 ae ad 20 1e 80 2f 7b 6a ce 6f 6c d0 a7 43 ba 78 ae ad
命令行
openssl enc
通常使用 PBKDF1 的變體從您輸入的密碼或密碼片語派生實際密鑰和 IV(儘管 ECB 忽略 IV)進行基於**密碼的加密。**要獲得“原始”加密,您必須使用(大寫)以十六進制指定密鑰,在這種情況下是無關緊要的(因為它僅適用於 PBKDF)。除了 OpenSSL 的最新版本(我的測試系統有一個較舊的版本)之外,即使使用的密碼/模式不需要它,例如 ECB ,您也必須指定十六進制格式。-K``-nosalt``-K``-iv
lin04:~ $ echo -n YELLOW SUBMARINE |od -tx1 |awk '$1="";gsub(/ /,"")' 59454c4c4f57205355424d4152494e45 lin04:~ $ echo -n 0123456789abcdef |openssl aes-128-ecb -nopad \ -K 59454c4c4f57205355424d4152494e45 -iv 00 |od -tx1 0000000 20 1e 80 2f 7b 6a ce 6f 6c d0 a7 43 ba 78 ae ad 0000020
超出了您的問題範圍,但我希望您知道在大多數情況下使用 ECB 是一個非常糟糕的主意。我在這里和 security.SE 中可能已經看到了幾十個問題和答案。作為最近最明顯的例子,請參閱 Adobe 密碼洩露事件,由於使用 ECB,許多密碼被破解。