4

I have a value that was encrypted using PHP openssl using cipher AES-CBC-256 but the passphrase for the final value was also encrypted using the same method. openssl_encrypt($key, $cipher, $passphrase, 0, $iv)

I need to be able to unencrypt this data using Python but I'm running into block-size issues.

Here's some of the code I have so far. I have tested decrypting this in PHP and it works properly. My final value in this example should be 'Jimmy'.

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

localKey = base64.b64decode('Po0KPxyF')
localIv = base64.b64decode('s8W+/a4jkp9mhO3NkCL7Yg==')

encrypted_value = base64.b64decode('hl5n6Nq5QYtgKIyLEVCupA==')
encrypted_key = base64.b64decode('MGRHRFlaMzhCR0lxb2VHS1JHQXcrWkV2bkJpNWFZb3cybW9iQW5KYTlOU0xKK1FHc2pPUW1MUE9JRU5zTXN1Rg==')
encrypted_iv = base64.b64decode('J31SrExr7KKIOertYIPhpQ==')

# First need to encrypted key that uses the local key as the passphrase
cipher_key = AES.new(pad(localKey,16), AES.MODE_CBC, localIv)
decrypted_key = cipher_key.decrypt(encrypted_key)

# Then decrypted the final value using the newly decrypted key
cipher_key = AES.new(unpad(decrypted_key,16), AES.MODE_CBC, encrypted_iv)
decrypted_value = cipher_key.decrypt(encrypted_value)
2
  • 1
    Can you please provide the corresponding PHP script? Commented Apr 29 at 6:48
  • I agree, people probably need to see what you're (exactly) doing in PHP to get the encrypted string. Commented Apr 29 at 7:06

1 Answer 1

9

I managed to figure out the PHP code that does the decryption:

$localKey  = base64_decode('Po0KPxyF');
$localIv = base64_decode('s8W+/a4jkp9mhO3NkCL7Yg==');

$encrypted_value = base64_decode('hl5n6Nq5QYtgKIyLEVCupA==');
$encrypted_key = base64_decode('MGRHRFlaMzhCR0lxb2VHS1JHQXcrWkV2bkJpNWFZb3cybW9iQW5KYTlOU0xKK1FHc2pPUW1MUE9JRU5zTXN1Rg==');
$encrypted_iv = base64_decode('J31SrExr7KKIOertYIPhpQ==');

$decrypted_key = openssl_decrypt(base64_decode($encrypted_key), 'aes-256-cbc', $localKey, OPENSSL_RAW_DATA, $localIv);
$decrypted_value  = openssl_decrypt($encrypted_value, 'aes-256-cbc', $decrypted_key, OPENSSL_RAW_DATA, $encrypted_iv);
echo $decrypted_value;

Output:

s:5:"Jimmy";

(Demo)

Remarks:

  • $localKey is shorter than 256 bits, so openssl_decrypt() pads it with null bytes
  • $encrypted_key was base64-encoded twice, so you need to decode it twice
  • The value contained in $decrypted_value was serialized with serialize()

Here is a Python implementation (based on PyCryptodome):

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

localKey = base64.b64decode('Po0KPxyF')
localIv = base64.b64decode('s8W+/a4jkp9mhO3NkCL7Yg==')

encrypted_value = base64.b64decode('hl5n6Nq5QYtgKIyLEVCupA==')
encrypted_key = base64.b64decode('MGRHRFlaMzhCR0lxb2VHS1JHQXcrWkV2bkJpNWFZb3cybW9iQW5KYTlOU0xKK1FHc2pPUW1MUE9JRU5zTXN1Rg==')
encrypted_iv = base64.b64decode('J31SrExr7KKIOertYIPhpQ==')

# First need to encrypted key that uses the local key as the passphrase
cipher_key = AES.new(localKey.ljust(32, b'\0'), AES.MODE_CBC, localIv)
decrypted_key = cipher_key.decrypt(base64.b64decode(encrypted_key))

# Then decrypted the final value using the newly decrypted key
cipher_key = AES.new(unpad(decrypted_key,16), AES.MODE_CBC, encrypted_iv)
decrypted_value = cipher_key.decrypt(encrypted_value)
value = unpad(decrypted_value,16).decode()
print(value)

Output:

s:5:"Jimmy";

(Demo)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.