1 回答

TA貢獻1853條經驗 獲得超6個贊
在 PHP 代碼中(更準確地說是openssl_encrypt
),明確指定了 AES 變體,例如當前情況下的aes-128-...
,即 PHP 使用 AES-128。太長的鍵會被截斷,太短的鍵會用0
值填充。由于hash
PHP 代碼中的方法以十六進制字符串形式返回其結果,因此 16 字節 MD5 哈希值由 32 個字符(32 字節)表示,即在當前情況下 PHP 使用密鑰的前 16 個字節 (AES-128)。
Python 代碼中的方法hexdigest
也以十六進制字符串形式返回結果。然而,在Python代碼中(更準確地說是PyCryptodome),AES變體由密鑰大小指定,即Python代碼使用完整的32字節密鑰,因此使用AES-256。
不同的密鑰和 AES 變體是導致不同結果的主要原因。要解決此問題,兩個代碼中必須使用相同的密鑰和 AES 變體:
選項 1 是在 Python 代碼中也使用 AES-128。這可以通過以下更改來實現:
obj?=?AES.new(ENC_KEY[:16].encode("utf8"),?AES.MODE_CFB,?IV.encode("utf8"))
然后輸出
b0016a55
是按照 PHP 代碼的結果aes-128-cfb8
。選項 2 是在 PHP 代碼中也使用 AES-256。
aes-128...
這可以通過替換來完成aes-256...
然后輸出是aes-256-cfb8-1:?117c1974 aes-256-cfb1-1:?54096db1 aes-256-cfb-1?:?11bfdaa9
正如預期的那樣, 的輸出117c1974
與aes-128-cfb8
Python 代碼的原始值相匹配。
CFB 模式將分組密碼更改為流密碼。從而n
在每個加密步驟中對位進行加密,這稱為CFBn
。
PHP 中也使用術語CFBn
(或),即表示 1 位、8 位(= 1 字節)和整個塊(16 字節)的加密。在 Python 中,每步的位數用 指定。cfbn
CFB1
CFB8
CFB
segment_size
...-cfb8
即PHP 中的對應項是 Python 中,?PHP 中segment_size = 8
的對應項是Python 中。...-cfb
segment_size = 128
下面假設兩個代碼中使用相同的密鑰和相同的 AES 變體。
由于是默認值,Python 代碼的結果與 PHP 代碼的segment_size = 8
結果相同。...-cfb8
如果選擇在 Python 代碼中,則結果與在 PHP 代碼中segement_size = 128
相同。...-cfb
但是,在 PyCryptodome 中,該值segment_size
必須是 8 的整數倍,否則錯誤消息“segment_size”必須為正數并顯示8 位的倍數。因此,CFB1
PyCryptodome 不支持該模式。
另請注意:
摘要的結果也可以在兩種代碼中以二進制形式返回,而不是以十六進制字符串形式返回。為此,
hash
必須將 PHP 方法的第三個參數設置為TRUE
(默認值FALSE
:)。在Python中,只需使用digest
方法而不是hexdigest
.在 PHP 代碼中,對于像 CFB 這樣的流密碼模式,填充會自動禁用,因此標志
OPENSSL_ZERO_PADDING
(可用于顯式禁用填充)沒有任何區別。utf8_encode
允許您從 ISO-8859-1 編碼轉換為 UTF-8,但由于它$ENC_KEY
由字母數字字符(十六進制編碼)組成,因此沒有任何效果。但是,一般來說,任意二進制數據(例如摘要的結果)不得采用 UTF8 編碼,因為這會損壞數據。還有其他用于此目的的編碼,例如 Base64。如果摘要的結果以二進制形式返回(參見第一點),則不能執行 UTF8 編碼。在 CFB 模式的上下文中,舊版 PyCrypto 庫中存在一個錯誤,該錯誤要求明文的長度是段大小的整數倍。否則會出現以下錯誤:輸入字符串的長度必須是段大小 16 的倍數。
- 1 回答
- 0 關注
- 260 瀏覽
添加回答
舉報