I've got a encrypt/decrypt class setup based on this SO answer. I've tested it and it works fine. It's not working for a new API I'm pulling information from. The new API is built with PHP and is using the following package to encrypt information: https://laravel.com/docs/8.x/encryption using Laravel Crypt() command. All encrypted values are encrypted using OpenSSL and the AES-256-CBC cipher.
The enc
value after the first line of the decrypt method
def decrypt(self, enc):
enc = base64.b64decode(enc)
iv = enc[:AES.block_size]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
looks like this (Don't worry, this is just non-sensitive demo data):
b"{'iv': 'Ld2pjRJqoKcWnW1P3tiO9Q==', 'value': 'M9QeHtbybeUxAVuIRcQ3bA==', 'mac': 'xxxxxx......'}"
, which basically looks like a byte-string JSON. The testing encryption key is base64:69GnnXWsW1qnW+soLXOVd8Mi4AdXKBFfkw88/7F2kSg=
.
I know I can turn it into a dictionary like this
import json
d = json.loads(enc)
How should I manipulate values from this dictionary to prepare it to be decrypted like other encrypted text this class can successfully decrypt?
Based on comments I've tried to modify the method to look like this:
def decrypt(self, encrypted):
enc = base64.b64decode(encrypted)
if b'{"iv":' == enc[:6]:
d = json.loads(enc)
iv = base64.b64decode(d['iv'])
val = base64.b64decode(d['value'])
else:
iv = enc[:AES.block_size]
val = enc[AES.block_size:]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return self._unpad(cipher.decrypt(val)).decode('utf-8')
This still does not work. It doesn't crash, but I'm getting a blank string back (''
) and I know that's not what was encrypted. The answer should be 'Demo'
The code in the "Update" section of the question will work without any changes. You just need to make sure to remove the "base64:" prefix in the encryption key provided. Once that is removed, it will work as expected.