起因我在php服务端接口,会有一个key。key是使用动态AES-GCM-128方案进行加密。然后解密的时候发现就是错误。
最后发现是密匙赋值存在问题。这个小问题,尝试了2个多小时,最后得出原来是密匙定义不同。
<?php
// 密钥
$key = 'HdnJUPMSnC1ojtiw';
// 生成一个 16 字节的随机 IV
$iv = openssl_random_pseudo_bytes(16);
// 待加密的明文
$plaintext = "这是一个明文信息";
// 使用 AES-128-GCM 进行加密
if (in_array('aes-128-gcm', openssl_get_cipher_methods()))
{
$ciphertext = openssl_encrypt($plaintext, 'aes-128-gcm', $key, $options=OPENSSL_RAW_DATA, $iv, $tag);
// 输出结果
echo "加密后的密文 (Base64编码): " . base64_encode($iv.$ciphertext.$tag) . PHP_EOL;
}
else
{
echo "AES-128-GCM 不支持" . PHP_EOL;
}
?>
下面是Python结构代码。
from Cryptodome.Cipher import AES
import base64
# 密钥
key = b'HdnJUPMSnC1ojtiw'
# 以下是 PHP 输出的 Base64编码后的字符串
# 例如:base64_ciphertext_tag = 'Base64编码后的字符串'
base64_ciphertext_tag = '这里填入 PHP 脚本输出的 Base64 编码后的字符串'
# Base64 解码
ciphertext_tag = base64.b64decode(base64_ciphertext_tag)
# 提取 IV, 密文和 Tag
iv = ciphertext_tag[:16]
ciphertext = ciphertext_tag[16:-16]
tag = ciphertext_tag[-16:]
# 创建 AES-GCM 解密对象
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
# 解密数据
try:
decrypted_data = cipher.decrypt_and_verify(ciphertext, tag)
print("解密后的明文:", decrypted_data.decode('utf-8'))
except (ValueError, KeyError):
print("解密失败或者验证 Tag 失败")
总结
php的密匙 就是字符,但是到了Python它的密匙是 需要引入 b'密匙内容',否则就是会解码失败。
另外请注意,如果Python解码失败记得先安装这个库。
pip install pycryptodome