PythonアプリケーションとPHP Webサイトを使用して、特定のネットワーク層からメッセージを送信しています。私の仕事は、そのチャンネルを使ってAESで暗号化され、base64でエンコードされたすべてのメッセージを送信することです。暗号化キーは、両者のために手動で事前共有されます。私のPHPでopenssl_encryptを使用したPython-to-PHP互換AES暗号化AES-CBC
、私は、最終的なメッセージテキストを作成するには、このコードを使用し$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;
}
そして私は、base64バイトデータを取得し、魔法を剥ぎ取り、私のPythonアプリケーションでは、このようなメッセージが表示されます。このメッセージを解読するための互換性のあるAES暗号を作成するサンプルが見つかりません。
キーと「マジック」はあらかじめ共有され、両側で既知の値のみですが、これは正しいですか? IVが必要ですか?
私の暗号化されたメッセージでは機能しないので、ここの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'))
デコードの問題で最後の行に失敗します。 "ignore"デコードモードは空文字列を返します。
# 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の文字と数字でキーを作成すると、キー空間が大幅に縮小されます。 –