You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Socket AES256加密后,JS接收ArrayBuffer解密失败求助

Python AES-256 Socket加密 + JS Crypto-JS解密 修复方案

嘿,我一看你这代码就知道问题出在哪了——两端的加密解密参数完全没对齐,导致解密后拿不到有效数据。我给你拆解下问题,再直接上修复后的代码:

核心问题分析

  1. Python端没做PKCS7填充:你JS端解密用的是Pkcs7 padding,但Python加密时注释掉了填充逻辑,当明文长度不是16字节(AES块大小)的整数倍时,加密出来的内容本身就有问题,解密自然失败。
  2. JS端硬编码了IV:Python加密时生成了随机IV,还把IV和密文拼接在一起发送了,但你JS端却用全0的IV去解密,这完全不匹配,肯定解不出东西。
  3. Base64处理错误:Python发送的是Base64编码后的字节,但你JS端直接把ArrayBuffer转成WordArray,相当于处理的是Base64字符串的原始字节,而不是真正的加密数据。

修复后的Python代码

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad
import hashlib
import base64

class AES_256(object):
    def __init__(self, key):
        self.bs = AES.block_size
        # 用SHA256生成32字节的AES-256密钥,和JS端逻辑对齐
        self.key = hashlib.sha256(key.encode("utf-8")).digest()
    
    def encrypt(self, raw):
        # 统一处理明文:字符串转字节,然后做PKCS7填充
        if isinstance(raw, str):
            raw = raw.encode('utf-8')
        padded_raw = pad(raw, self.bs)
        # 生成随机IV(必须和密文一起发送,JS端要用来解密)
        iv = get_random_bytes(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        # 拼接IV和密文,再Base64编码后发送
        encrypted_data = iv + cipher.encrypt(padded_raw)
        return base64.b64encode(encrypted_data)

# 示例:加密并准备发送数据
encryption_256 = AES_256("password")
buffer = "你要发送的原始数据,可以是字符串或字节"
encrData = encryption_256.encrypt(buffer)
# 这里直接把encrData通过Socket发送即可(它已经是bytes类型)

修复后的JavaScript代码

// 接收Socket传来的ArrayBuffer并解密
function decryptSocketData(arrayBuffer, password) {
    // 1. 把ArrayBuffer转成UTF-8字符串(Python发的是Base64编码的ASCII串)
    const base64Str = new TextDecoder('utf-8').decode(arrayBuffer);
    
    // 2. Base64解码,得到包含IV和密文的二进制数据
    const encryptedData = CryptoJS.enc.Base64.parse(base64Str);
    
    // 3. 提取IV(前16字节,AES块大小)和密文(剩下的部分)
    const iv = CryptoJS.lib.WordArray.create(encryptedData.words.slice(0, 4), 16);
    const ciphertext = CryptoJS.lib.WordArray.create(
        encryptedData.words.slice(4), 
        encryptedData.sigBytes - 16
    );
    
    // 4. 生成和Python端一致的AES密钥
    const key = CryptoJS.SHA256(password);
    
    // 5. 解密,参数和Python端完全对齐
    const decrypted = CryptoJS.AES.decrypt(
        { ciphertext: ciphertext },
        key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );
    
    // 6. 转成UTF-8字符串返回
    return decrypted.toString(CryptoJS.enc.Utf8);
}

// 示例使用:假设encodedFrame.data是Socket接收的ArrayBuffer
const decryptedResult = decryptSocketData(encodedFrame.data, "password");
console.log("解密后的数据:", decryptedResult);

关键修复点说明

  • 填充对齐:Python端新增pad处理,和JS端的Pkcs7 padding完全匹配,解决明文长度不兼容的问题。
  • IV动态提取:不再硬编码IV,而是从加密数据中取出Python生成的随机IV,保证解密时参数一致。
  • Base64正确解码:先把ArrayBuffer转成Base64字符串再解码,拿到真正的加密内容,而不是处理Base64的原始字节。
  • 密钥生成简化:JS端直接用CryptoJS.SHA256(password)生成密钥,和Python端的SHA256处理逻辑完全一致,无需额外转码。

内容的提问来源于stack exchange,提问作者CodeDezk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:17:53