求对应AES-CCM加密解密JS函数的Python3等效实现方案
解决方案
实现说明
你可以直接使用PyCryptodome库实现对应功能,只需将SJCL的参数映射到PyCryptodome的参数即可,映射规则如下:
- SJCL中的
ks: 256对应AES-256,密钥长度为32字节,直接将十六进制密钥转为bytes即可 - SJCL中的
iv参数对应PyCryptodome的nonce,你示例中是取密钥前16个十六进制字符转为8字节bytes,符合CCM模式nonce长度要求(7~13字节) - SJCL中的
ts: 128对应mac_len=16(128位=16字节) - SJCL中的
adata: ""对应空关联数据,无需额外配置 - 你示例中salt为空,且直接传入预先生成的密钥而非密码字符串,因此
iter(迭代次数)参数不会生效,无需处理密钥派生步骤 - SJCL返回的密文是「加密后的明文 + MAC标签」拼接后的结果,解密时需要拆分出前半部分作为密文,后16字节作为校验标签
完整实现代码
首先安装依赖:
pip install pycryptodome
代码示例
from Crypto.Cipher import AES # 配置参数和JS代码保持一致 HEX_KEY = "ef530e1d82c154170296467bfe40cdb47b9ad77e685bbf8336b145dfa0e85640" KEY = bytes.fromhex(HEX_KEY) # nonce取密钥前16个十六进制字符转bytes NONCE = bytes.fromhex(HEX_KEY[:16]) MAC_LEN = 16 def decrypt(ct_hex: str) -> str: encrypted_data = bytes.fromhex(ct_hex) # 拆分密文和MAC标签 ciphertext = encrypted_data[:-MAC_LEN] tag = encrypted_data[-MAC_LEN:] cipher = AES.new(KEY, AES.MODE_CCM, nonce=NONCE, mac_len=MAC_LEN) # 解密同时校验标签 plaintext = cipher.decrypt_and_verify(ciphertext, tag) return plaintext.decode("utf-8") def encrypt(plaintext: str) -> str: cipher = AES.new(KEY, AES.MODE_CCM, nonce=NONCE, mac_len=MAC_LEN) ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode("utf-8")) # 拼接密文和标签后转十六进制返回,和JS逻辑一致 return (ciphertext + tag).hex() # 测试 if __name__ == "__main__": test_ct = "fa90bcdedbfe7ba89b69216e352a90fa57a63871fc4da7e69ab7f897f427f8e3" print("解密结果:", decrypt(test_ct)) # 输出:解密结果: my secret string new_ct = encrypt("my secret string") print("新生成密文:", new_ct) print("新密文解密结果:", decrypt(new_ct))
注意事项
CCM模式要求同一密钥对应的每条消息必须使用唯一的nonce,你示例中固定使用密钥前半段作为nonce的做法仅适合测试场景,生产环境使用时必须为每条消息生成独立随机nonce,否则会有严重的安全漏洞。
内容的提问来源于stack exchange,提问作者aaronk6
相关产品推荐
相关产品推荐

