Aes

為什麼 PyCrypto 和 M2Crypto 不在這裡產生與 OpenSSL 相同的結果(AES-128 ECB)

  • February 21, 2015

如果我執行以下命令,對於 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 中可能已經看到了幾十個問題和答案。作為最近最明顯的例子,請參閱 Adob​​e 密碼洩露事件,由於使用 ECB,許多密碼被破解。

引用自:https://crypto.stackexchange.com/questions/24050