使用Python解密WebCrypto AES-GCM加密数据失败问题排查
问题解答
关于IV和Nonce的关系
AES-GCM模式中的IV(初始化向量)和Nonce是完全相同的概念,只是不同加密库的命名习惯不同:WebCrypto API里叫IV,PyCryptodome里叫Nonce,两者功能、要求完全一致,不用纠结命名差异。
解密失败的核心原因
WebCrypto的subtle.encrypt方法返回的结果是**密文 + 认证标签(Tag)**的拼接(GCM模式默认生成128位/16字节的标签),你的Python代码犯了两个关键错误:
- 把加密后的完整数据当成了纯密文,没有拆分出标签
- 错误地将IV(Nonce)作为标签传入
decrypt_and_verify方法,导致完整性验证失败
修正后的Python解密代码
from Crypto.Cipher import AES hex_key = '0db43c44650a8b71547dbc6951432f0c545509814d6bca1a10e387ad2d16bc4a' encrypted_data = '37183efb9e4ce92265d1144110cdbe1e768a85f9630bf872' iv_hex = '43005ad454f6e3c6e3ead90f7137f007' # 转换为字节格式 key = bytes.fromhex(hex_key) full_data = bytes.fromhex(encrypted_data) nonce = bytes.fromhex(iv_hex) # GCM默认标签长度16字节,拆分密文和标签 ciphertext = full_data[:-16] tag = full_data[-16:] # 执行解密与完整性验证 cipher = AES.new(key, AES.MODE_GCM, nonce) try: decrypted = cipher.decrypt_and_verify(ciphertext, tag) print(decrypted.decode('utf-8')) # 输出: Hi there except ValueError: print("Decryption failed")
补充说明
- WebCrypto的
encrypt方法会自动将密文和标签拼接返回,无需手动处理;而PyCryptodome需要明确拆分两者 - GCM模式的标签长度可自定义,但WebCrypto默认使用128位,因此拆分时取最后16字节即可
- IV/Nonce、密钥、密文、标签必须完全匹配,任何一项错误都会导致解密失败
内容的提问来源于stack exchange,提问作者xrd
相关产品推荐
相关产品推荐

