我有一个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字母和数字组成的密钥可显着减少可能的密钥空间。 –