AES-CCM解密:Python正常运行但PHP实现失败求助
AES-CCM解密在PHP中返回空结果的解决提示
我需要解密智能设备获取的文本,Python中使用cryptography库的AESCCM可以正常解密,但PHP调用openssl_decrypt返回空结果,无任何错误提示,openssl_error_string()也无输出。环境支持AES-CCM(修改后的示例可运行),但设备返回的13字节nonce无法修改。
Python 可运行代码
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()
PHP 无法运行代码
<?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; } ?>
解决提示
检查OpenSSL对CCM nonce长度的默认限制:执行
echo openssl_cipher_iv_length('aes-256-ccm');,如果返回12,说明PHP的OpenSSL默认期望12字节nonce,而你的13字节nonce不符合默认要求,这是空返回的核心原因。调整
openssl_decrypt参数:显式传递空附加数据(AAD)并禁用填充,尝试修改调用代码:
$decrypted = openssl_decrypt( $payload, $cipher, $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $nonce, $mic, '' // 空AAD,对应Python中的None参数 );
- 使用第三方加密库phpseclib:如果OpenSSL的限制无法绕过,phpseclib对CCM模式的参数支持更灵活,可直接指定13字节nonce和4字节tag长度。示例代码(需先通过Composer安装
phpseclib/phpseclib):
<?php require 'vendor/autoload.php'; use phpseclib3\Crypt\AES; $payload = hex2bin("73ad3f07fe89"); $mic = hex2bin("d8c82d06"); $key = hex2bin("D77B34645356FB1333BAD6357B38CCCF"); $nonce = hex2bin("7cc6b66242d3e3fc4512ac1267"); $aes = new AES('ccm'); $aes->setKey($key); $aes->setNonce($nonce); $aes->setTag($mic); $aes->disablePadding(); $decrypted = $aes->decrypt($payload); echo bin2hex($decrypted); // 应输出Python中解密成功的结果 ?>
- 确认版本兼容性:确保PHP版本≥7.1,OpenSSL版本≥1.1.0,这些版本对CCM模式的非默认参数支持更完善。
内容的提问来源于stack exchange,提问作者Simon Wick
相关产品推荐
相关产品推荐

