【发布时间】:2021-06-14 00:07:42
【问题描述】:
我正在尝试使用 AES GCM 加密算法在 JS 前端加密并在 python 后端解密。我将Web cryptography api 用于JS 前端,将python cryptography library 用于python 后端作为加密库。我现在已经在两侧固定了 IV。我在两边都实现了加密-解密代码,它们在每一边都工作。但我认为填充的方式不同,似乎无法弄清楚填充是如何在网络密码学 api 中完成的。下面是python后端的加解密:
def encrypt(derived_key, secret):
IV = bytes("ddfbccae-b4c4-11", encoding="utf-8")
aes = Cipher(algorithms.AES(derived_key), modes.GCM(IV))
encryptor = aes.encryptor()
padder = padding.PKCS7(128).padder()
padded_data = padder.update(secret.encode()) + padder.finalize()
return encryptor.update(padded_data) + encryptor.finalize()
def decrypt(derived_key, secret):
IV = bytes("ddfbccae-b4c4-11", encoding="utf-8")
aes = Cipher(algorithms.AES(derived_key), modes.GCM(IV))
decryptor = aes.decryptor()
decrypted_data = decryptor.update(secret)
unpadder = padding.PKCS7(128).unpadder()
return unpadder.update(decrypted_data) + unpadder.finalize()
下面是加解密代码的JS代码:
async function encrypt(secretKey, message) {
let iv = "ddfbccae-b4c4-11";
iv = Uint8Array.from(iv, x => x.charCodeAt(0))
let encoded = getMessageEncoding(message);
ciphertext = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
},
secretKey,
encoded
);
return ciphertext;
}
async function decrypt(secretKey, cipherText) {
iv = "ddfbccae-b4c4-11";
iv = Uint8Array.from(iv, x => x.charCodeAt(0))
try {
let decrypted = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv
},
secretKey,
cipherText
);
let dec = new TextDecoder();
console.log("Decrypted message: ");
console.log(dec.decode(decrypted));
} catch (e) {
console.log("error");
}
}
我尝试在 JS 端加密并在 python 端解密。但我收到以下错误:
如果我尝试在两边加密相同的字符串,我会得到以下输出: 在python中加密文本:\x17O\xadn\x11*I\x94\x99\xc6\x90\x8a\xa9\x9cc=
在JS中密文:\x17O\xadn\x11*I\xdf\xe3F\x81(\x15\xcc\x8c^z\xdf+\x1d\x91K\xbc
如何解决这个填充问题?
【问题讨论】:
-
GCM 是一种流密码模式,不应用填充,Cryptography 也以不同的方式实现 GCM。在您的实现中,至少缺少该标签。此外,建议使用 12 字节的随机数。
-
好吧,我的错。谢谢。
标签: javascript python cryptography webcrypto-api python-cryptography