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

NodeJS无法解密C++ AES-256-CBC加密字符串问题求助

AES256-CBC跨语言解密失败问题解决

问题背景

我用C的OpenSSL AES库加密字符串,转Base64后发送给NodeJS服务解密,但NodeJS始终解密失败。采用AES256 CBC算法,C端已手动实现PKCS#7填充逻辑。

核心问题

C++与NodeJS对密钥(key)和初始化向量(IV)的解析逻辑完全不一致:

  • C++端:直接把字符串当作ASCII字节数组使用。比如aes_key是64个字符的字符串,AES256取前32个字符的ASCII值作为密钥;aes_iv是32个字符的字符串,取前16个字符的ASCII值作为IV。
  • NodeJS端:用Buffer.from(..., 'hex')解析,把字符串当作十六进制编码处理——64个字符会被解析成32字节密钥,32个字符解析成16字节IV,和C++端的字节内容完全不匹配。

修复方案

统一两端的key/IV解析逻辑,以下两种方案二选一:

方案一:修改NodeJS端,匹配C++的ASCII解析逻辑

将NodeJS的key和IV改为直接取字符串的ASCII字节,并截取对应长度:

const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 修改key和IV的解析方式,与C++对齐
const aes_key = Buffer.from("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 'utf8').slice(0, 32);
const aes_iv = Buffer.from("0123456789abcdef0123456789abcdef", 'utf8').slice(0, 16);

function DecryptAES(cipherText) {
    const decipher = crypto.createDecipheriv('aes-256-cbc', aes_key, aes_iv);
    let decrypted = decipher.update(cipherText, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

app.post('/decrypt', (req, res) => {
    const { encryptedText } = req.body;

    if (!encryptedText) {
        return res.status(400).json({ error: 'Missing encryptedText in request body' });
    }

    try {
        const decryptedText = DecryptAES(encryptedText);
        res.send(decryptedText);
        console.log(decryptedText);
    } catch (error) {
        console.error('Decryption failed:', error);
        res.status(500).send('Decryption failed');
    }
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});

方案二:修改C++端,匹配NodeJS的十六进制解析逻辑

在C++中新增十六进制转字节数组的函数,将key和IV字符串按十六进制解析后再使用:

#include <iostream>
#include <string>
#include <openssl/aes.h>
#include <vector>
#include <sstream>
#include <iomanip>

#include "base64.h"

using namespace std;

// 新增:十六进制字符串转字节数组
vector<unsigned char> hex_to_bytes(const string& hex_str) {
    vector<unsigned char> bytes;
    for (size_t i = 0; i < hex_str.length(); i += 2) {
        string byte_sub = hex_str.substr(i, 2);
        unsigned char byte = static_cast<unsigned char>(strtol(byte_sub.c_str(), nullptr, 16));
        bytes.push_back(byte);
    }
    return bytes;
}

// AES加密密钥和IV的十六进制字符串
const string aes_key_hex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
const string aes_iv_hex = "0123456789abcdef0123456789abcdef";

string EncryptAES(const string& plainText) {
    AES_KEY enc_key;
    vector<unsigned char> aes_key = hex_to_bytes(aes_key_hex);
    AES_set_encrypt_key(aes_key.data(), 256, &enc_key);

    // PKCS#7填充逻辑不变
    int paddingLength = AES_BLOCK_SIZE - (plainText.length() % AES_BLOCK_SIZE);
    if (paddingLength == 0) {
        paddingLength = AES_BLOCK_SIZE;
    }
    string paddedText = plainText;
    for (int i = 0; i < paddingLength; ++i) {
        paddedText.push_back(static_cast<char>(paddingLength));
    }

    // 加密逻辑,使用解析后的IV
    vector<unsigned char> aes_iv = hex_to_bytes(aes_iv_hex);
    string cipherText;
    cipherText.resize(paddedText.length());
    AES_cbc_encrypt(reinterpret_cast<const unsigned char*>(paddedText.c_str()), 
                    reinterpret_cast<unsigned char*>(&cipherText[0]), 
                    paddedText.length(), 
                    &enc_key, 
                    aes_iv.data(), 
                    AES_ENCRYPT);

    return cipherText;
}

int main() {
    string plainText = "Hello, this is a secret message.";
    string encryptedText = EncryptAES(plainText);
    auto encodedText = base64_encode(encryptedText);
    cout << "Encoded text: " << encodedText << endl;
    return 0;
}

验证说明

修改后NodeJS端无需修改自动填充逻辑(默认开启PKCS#7填充匹配C++端),用你提供的测试Base64字符串即可正常解密出明文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:31:00