I'm trying to decrypt a text which I'm getting from a smart device. It works in Python, but doesn't work in PHP. I'm just getting an empty answer from openssl_decrypt
, there is no error or warning nor any error in openssl_error_string()
. I need to do it in PHP. I've already read this answer https://stackoverflow.com/a/61797909, but I'm still not able to fix my PHP-script. Because I'm getting the data from a device, I'm not able to change the length of the nonce, if that should be a problem (it's 13 bytes).
A modified AES-CCM version of this example https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-a-php-string/ works, so it doesn't seem to be a problem with my PHP-installation.
The working python-script (don't worry, key and nonce will be changed):
from __future__ import annotations
import binascii
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESCCM
def decrypt_payload(
payload: bytes, mic: bytes, key: bytes, nonce: bytes
) -> dict[str, float] | None:
cipher = AESCCM(key, tag_length=4)
try:
data = cipher.decrypt(nonce, payload + mic, None)
print("Decryption succeeded, decrypted data:", data.hex())
except ValueError as error:
print()
print("Decryption failed:", error)
return None
# =============================
# main()
# =============================
def main() -> None:
payload = bytes(bytearray.fromhex("73ad3f07fe89"))
mic = bytes(bytearray.fromhex("d8c82d06"))
key = bytes(bytearray.fromhex("D77B34645356FB1333BAD6357B38CCCF"))
nonce = bytes(bytearray.fromhex("7cc6b66242d3e3fc4512ac1267"))
decrypt_payload(payload=payload, mic=mic, key=key, nonce=nonce)
if __name__ == "__main__":
main()
The not working PHP-code:
<?php
$cipher = 'aes-256-ccm';
$payload = hex2bin("73ad3f07fe89");
$mic = hex2bin("d8c82d06");
$key = hex2bin("D77B34645356FB1333BAD6357B38CCCF");
$nonce = hex2bin("7cc6b66242d3e3fc4512ac1267");
if (in_array($cipher, openssl_get_cipher_methods())){
$decrypted = openssl_decrypt($payload, $cipher, $key, OPENSSL_RAW_DATA, $nonce, $mic);
echo "Error: " . openssl_error_string();
echo $decrypted;
}
?>
Thanks in advance for any hint!
Tested using PHP-generated values:
97093f1536825df218900bdd45d26a47
ecf6b43043e5e3444a89a39488
ea133e49
16d041edcde3ecfe6167d4da152d
No issues decrypting to the string "this is a test" in PHP. The 13 byte IV is therefore not an issue. However, Python fails with an "InvalidTag" error with these test values.
Upon further testing, the issue seems to be the key length. Your key is only 128-bit; when using AES-256, this should be a 256-bit key. Python's key padding is apparently different from PHP's.