在 Cryptodome python 中解密 CyproJS AES 加密

decrypting CyproJS AES encryption in Cryptodome python

我正在尝试解密在 JavaScript 中使用 CryptoJS 编码的消息(在 python 中)。我在 python 中创建了一个 API 到 post 数据 我正在使用 postman 预请求脚本。

我遇到的错误:

ValueError: Data must be padded to 16 byte boundary in CBC mode

JavaScript 加密代码

var data = {"feature_0": 0,
            "feature_1": 0, 
            "feature_2": 0, 
            "feature_3": 0, 
            "feature_4": 0, 
            "feature_5": 0
           };
let password = "lazydog";
let salt = "salt";
let iterations = 128;
data = JSON.stringify(data);
let len = 16 - ((data.length) % 16);
data += len.toString().repeat(len);  --> removed (as suggested)
let bytes = CryptoJS.PBKDF2(password, salt, { keySize: 48, iterations: iterations });
let iv = CryptoJS.enc.Hex.parse(bytes.toString().slice(0, 32));
let key = CryptoJS.enc.Hex.parse(bytes.toString().slice(32, 96));

let encrypted = CryptoJS.AES.encrypt(data, key, {iv: iv}); //, mode: CryptoJS.mode.CBC
//encrypted = btoa(encrypted); --> removed (as suggested)
encrypted = encrypted.toString() -->added (as suggested)
postman.setGlobalVariable("data", encrypted);

python解密代码:

def decode(encrypted):
    data = b64decode(encrypted)  
    byte = PBKDF2("lazydog".encode("utf-8"), "salt".encode("utf-8"), 48, 128)
    iv = byte[0:16]
    key = byte[16:48]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    text = cipher.decrypt(data) ## error is at this line
    text = text[:-text[-1]].decode("utf-8")

    return text

如错误所说的填充问题我在JS代码中添加了填充。我仍然没有得到好的结果。 我在这里做错了什么?

加密后的字符串已经投递到API,API写入了python。 我不知道为什么,但是当加密传递给 python 时,“+”字符被替换为“”(space)。通过将 spaces 替换为 '+' 字符,我解决了问题。

代码

var data = {"feature_0": 0,
        "feature_1": 0, 
        "feature_2": 0, 
        "feature_3": 0, 
        "feature_4": 0, 
        "feature_5": 0
       };
let password = "lazydog";
let salt = "salt";
let iterations = 128;
data = JSON.stringify(data);
let bytes = CryptoJS.PBKDF2(password, salt, { keySize: 48, iterations: 
  iterations });
let iv = CryptoJS.enc.Hex.parse(bytes.toString().slice(0, 32));
let key = CryptoJS.enc.Hex.parse(bytes.toString().slice(32, 96));

let encrypted = CryptoJS.AES.encrypt(data, key, {iv: iv});
encrypted = encrypted.toString()
postman.setGlobalVariable("data", encrypted);

python代码

def decode(encrypted):
    encrypted = encrypted.replace(' ', '+') --> this line is added
    data = b64decode(encrypted)  
    byte = PBKDF2("lazydog".encode("utf-8"), "salt".encode("utf-8"), 48, 128)
    iv = byte[0:16]
    key = byte[16:48]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    text = cipher.decrypt(data) ## error is at this line
    text = text[:-text[-1]].decode("utf-8")

    return text

作为 CryptoJs 填充数据,隐式自定义填充已被删除。并删除了 btoa(这不是必需的)。然后将加密数据转换为String。 @Topaco 在评论中建议