I have the following 2 values : AES key it is a Java array of bytes
64,67,-65,88,-19,-118,-16,-53,-81,-98,44,-83,82,-90,124,112,-120,42,92,67,104,23,44,8,2,-96,-106,-28,57,99,76,73
IV also a Java array of bytes
50,52,3,36,-90,81,109,-56,24,122,-3,27,-96,56,118,-60
The encryption mode is : AES/CBC/PKCS5PADDING
Now I need to use these 2 values to decrypt my cipher text using python. I am trying to use pycrypto but am open on exploring other options as well. Now because Java's array of bytes is signed and (it looks like) python (2.7) does not recognize signed array of bytes, I am having trouble doing this decryption.
I did find a bunch of SO discussions around similar topics, but most of them were generating the IV and the key, and not really using an already existing one, for eg.
- Encrypt & Decrypt using PyCrypto AES 256
- Using a byte array as key for AES algorithm in Python (looked promising but did not help much)
- Python PyCrypto encrypt/decrypt text files with AES
So the above solutions have not worked for me, unless I did something fundamentally wrong while tweaking them for my need.
Here's one of my attempts (bits and pieces taken from the SO discussions mentioned above)
from Crypto import Random
from Crypto.Cipher import AES
import base64
key =
[64,67,-65,88,-19,-118,-16,-53,-81,-98,44,-83,82,-90,124,112,-120,42,92,67,104,23,44,8,2,-96,-106,-28,57,99,76,73]
iv = [50,52,3,36,-90,81,109,-56,24,122,-3,27,-96,56,118,-60]
aes_key = ''.join(map(lambda x: chr(x % 256), key))
iv_data = ''.join(map(lambda x: chr(x % 256), iv))
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def decrypt(ciphertext, key):
ciphertext = base64.b64decode(ciphertext)
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
And then calling decrypt() as :
decrypt('HaCiIld192v2QE3/zcuAxhpr39HRXvsHQYSJE/VT9FuWWK7envVDRaaDR6gpmh0zmw09/440O7UAtVb5qBLddZH37TASWUMXAN0Idy7B0VtpgPgMHOLGJG6axWCHgieaTleFDaRKP+z7WN+4fj5RGw==', aes_key)
gives the output as :
Out[9]: '\xdd\x99\xab\x8bI\xcb\xf0?\xcd
\x1c\x1eb\x109\xe8c\xc0\x105\xa6\xdb\xe4\xdb\x08\xc7\xdbHT\x08.\x10\x9e\xe1g\xfe\xd1\xc2\x92\xdbH\x8e\x9bV\xae^\r:\x98%\x8d\x06\xdf\xaf\t\xb5m\xfb\xf3Q+
s"CK\xf4\xc2\xe7\xd2\xfd\xfdq\xcc)\xcf\x99&\xffj\xc4\xc1\x1a$ML\xe9\xe7(\xef\x1c\x81vx\xf56'
I tried :
a = b'\xdd\x99\xab\x8bI\xcb\xf0?\xcd`\x1c\x1eb\x109\xe8c\xc0\x105\xa6\xdb\xe4\xdb\x08\xc7\xdbHT\x08.\x10\x9e\xe1g\xfe\xd1\xc2\x92\xdbH\x8e\x9bV\xae^\r:\x98%\x8d\x06\xdf\xaf\t\xb5m\xfb\xf3Q+`s"CK\xf4\xc2\xe7\xd2\xfd\xfdq\xcc)\xcf\x99&\xffj\xc4\xc1\x1a$ML\xe9\xe7(\xef\x1c\x81vx\xf56'
a.encode("hex")
and output is :
'dd99ab8b49cbf03fcd601c1e621039e863c01035a6dbe4db08c7db4854082e109ee167fed1c292db488e9b56ae5e0d3a98258d06dfaf09b56dfbf3512b607322434bf4c2e7d2fdfd71cc29cf9926ff6ac4c11a244d4ce9e728ef1c817678f536'
which is definitely not the plain text I was expecting. So I need help figuring this out, as to how can I decrypt (using Python 2.7) an AES encrypted cipher text given the key and IV as Java array of bytes?
As per suggestions in the comments below (@MaartenBodewes thanks) I tried this :
So, I checked the base64 of the bytearray, key, in java as :
byte arr[] = new byte[] {64,67,-65,88,-19,-118,-16,-53,-81,-98,44,-83,82,-90,124,112,-120,42,92,67,104,23,44,8,2,-96,-106,-28,57,99,76,73};
String base64 = new String(Base64.encodeBase64(arr));
and then to achieve the same in python did some changes to python code above to do the same as : (I realized that java treats a byte array as an array of signed 2s complement data, from an excellent discussion at Java byte array contains negative numbers, and so had to accommodate for that in python)
key = [64,67,-65,88,-19,-118,-16,-53,-81,-98,44,-83,82,-90,124,112,-120,42,92,67,104,23,44,8,2,-96,-106,-28,57,99,76,73]
b64encode(bytearray([(lambda x:int((bin(x & 0xff)),2))(x) for x in key]))
and both these resulted in the same output as :
QEO/WO2K8MuvniytUqZ8cIgqXENoFywIAqCW5DljTEk=
And I thought that not that I am sure that both these keys (Java and python) are the same, the decryption should work. And hence I tried once again:
decrypt('HaCiIld192v2QE3/zcuAxhpr39HRXvsHQYSJE/VT9FuWWK7envVDRaaDR6gpmh0zmw09/440O7UAtVb5qBLddZH37TASWUMXAN0Idy7B0VtpgPgMHOLGJG6axWCHgieaTleFDaRKP+z7WN+4fj5RGw==', str(aes_key))
And I got the exact same output as earlier:
'\xdd\x99\xab\x8bI\xcb\xf0?\xcd
\x1c\x1eb\x109\xe8c\xc0\x105\xa6\xdb\xe4\xdb\x08\xc7\xdbHT\x08.\x10\x9e\xe1g\xfe\xd1\xc2\x92\xdbH\x8e\x9bV\xae^\r:\x98%\x8d\x06\xdf\xaf\t\xb5m\xfb\xf3Q+
s"CK\xf4\xc2\xe7\xd2\xfd\xfdq\xcc)\xcf\x99&\xffj\xc4\xc1\x1a$ML\xe9\xe7(\xef\x1c\x81vx\xf56'