我有一個Python應用程序和PHP網站,它們通過一些特定的網絡層發送消息進行通信。我的任務是使用該通道發送AES加密和base64編碼的所有消息。加密密鑰是手動爲雙方預先共享的。使用openssl_encrypt AES-CBC進行Python-to-PHP兼容的AES加密
在我的PHP,我用這個代碼來創建一個名爲$payload
最終消息文本:
$key = substr('abdsbfuibewuiuizasbfeuiwhfashgfhj56urfgh56rt7856rh', 0, 32);
$magic = 'THISISANENCRYPTEDMESSAGE';
function crypted($data) {
global $key, $magic;
// serialize
$payload = json_encode($data);
// encrypt and get base64 string with padding (==):
$payload = @openssl_encrypt($payload, 'AES-192-CBC', $key);
// prepend with magic
$payload = $magic.$payload;
return $payload;
}
我和我的Python應用程序收到這樣的消息,剝離神奇,越來越的base64字節的數據。我無法找到一個示例使兼容的AES密碼解碼此消息的問題。
關鍵和「魔術」只是預先分享和雙方都知道的值,這是正確的嗎?我需要IV嗎?
這是來自SO的Python解決方案,不適用於我的加密消息。
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
class AESCipher:
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key):
self.key = key
self.iv = bytes(key[0:16], 'utf-8')
def __pad(self, text):
text_length = len(text)
amount_to_pad = AES.block_size - (text_length % AES.block_size)
if amount_to_pad == 0:
amount_to_pad = AES.block_size
pad = chr(amount_to_pad)
return text + pad * amount_to_pad
def __unpad(self, text):
pad = ord(text[-1])
return text[:-pad]
def encrypt(self, raw):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return b64encode(cipher.encrypt(raw))
def decrypt(self, enc):
enc = b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
r = cipher.decrypt(enc) # type: bytes
return self.__unpad(r.decode("utf-8", errors='strict'))
它在解碼問題的最後一行失敗。 「忽略」解碼模式返回空字符串。
# with magic: "THISISANENCRYPTEDMESSAGE8wZVLZpm7UNyUf26Kds9Gwl2TBsPRo3zYDFQ59405wI="
# contains: {'test': 'hello world'}
payload = '8wZVLZpm7UNyUf26Kds9Gwl2TBsPRo3zYDFQ59405wI='
aes = AESCipher('abdsbfuibewuiuizasbfeuiwhfashgfh')
print(aes.decrypt(payload))
舉:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "../test.py", line 36, in decrypt
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9e in position 0: invalid start byte
我在想什麼?
爲什麼你使用'text [-1]'(一個'x02'字節,所以你忽略了最後2個字節)來確定加密數據字符串的長度? –
使用密鑰作爲IV是一個非常聰明的想法。像真的不聰明。使用完全由ASCII字母和數字組成的密鑰可顯着減少可能的密鑰空間。 –