Nodejs AES 128 位 cbc模式加密 两种方式

Nodejs AES 128 位 cbc模式加密 两种方式

function encode(key,data) {
var cipher = require(‘crypto’).createCipher(‘aes128’,key);
return cipher.update(data,‘utf8’,‘binary’)+cipher.final(‘binary’);
}

这种方式 不填写 IV 还有一种方式

function encode(cryptkey, iv, cleardata) { 
var encipher = crypto.createCipheriv('aes-128-cbc', cryptkey, iv), 
    encoded  = encipher.update(cleardata, 'utf8', 'hex'); 
    encoded += encipher.final( 'hex' ); 
    return encoded; 
}

谁知道 第一种方式不填写IV 怎么用c++或者 PHP 来解密 ?


3 回复

Node.js AES 128 位 CBC 模式加密两种方式

在 Node.js 中使用 AES 加密时,CBC 模式需要一个初始化向量(IV)。如果你省略了 IV,可能会导致加密结果在不同的环境中无法正确解密。下面是两种加密方式的示例代码及其解释。

方法一:不提供 IV

const crypto = require('crypto');

function encode(key, data) {
    // 创建加密器
    const cipher = crypto.createCipher('aes-128-cbc', key);

    // 更新数据并最终完成加密
    let encrypted = cipher.update(data, 'utf8', 'base64');
    encrypted += cipher.final('base64');

    return encrypted;
}

// 示例
const key = '0123456789abcdef'; // 16 字节的密钥
const data = 'Hello World!';

console.log(encode(key, data)); // 输出加密后的字符串

注意: 这种方法默认会生成一个随机的 IV,并将其附加到加密文本中。因此,在解密时需要提取 IV 并重新使用它。

方法二:提供 IV

const crypto = require('crypto');

function encode(key, iv, data) {
    // 创建加密器
    const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);

    // 更新数据并最终完成加密
    let encrypted = cipher.update(data, 'utf8', 'base64');
    encrypted += cipher.final('base64');

    return encrypted;
}

// 示例
const key = '0123456789abcdef'; // 16 字节的密钥
const iv = Buffer.alloc(16, 0); // 16 字节的 IV
const data = 'Hello World!';

console.log(encode(key, iv, data)); // 输出加密后的字符串

如何使用 C++ 或 PHP 解密

C++

在 C++ 中使用 OpenSSL 库进行解密:

#include <openssl/aes.h>
#include <string>

std::string decrypt(const std::string& encryptedData, const std::string& key, const std::string& iv) {
    AES_KEY aesKey;
    AES_set_decrypt_key((unsigned char*)key.c_str(), 128, &aesKey);

    int len;
    unsigned char decrypted[AES_BLOCK_SIZE * 100];
    AES_cbc_encrypt((const unsigned char*)encryptedData.c_str(), decrypted, encryptedData.size(), &aesKey, (unsigned char*)iv.c_str(), AES_DECRYPT);

    return std::string((char*)decrypted, strlen((char*)decrypted));
}

int main() {
    std::string encryptedData = "your_encrypted_data_here";
    std::string key = "0123456789abcdef";
    std::string iv = "your_iv_here";

    std::cout << decrypt(encryptedData, key, iv) << std::endl;

    return 0;
}

PHP

在 PHP 中使用 openssl_decrypt 函数进行解密:

$key = '0123456789abcdef';
$iv = 'your_iv_here';
$encryptedData = 'your_encrypted_data_here';

$decryptedData = openssl_decrypt($encryptedData, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
echo $decryptedData;

注意: 在解密时,必须确保使用相同的密钥、IV 和加密模式。如果第一种方法没有提供 IV,则需要从加密文本中提取 IV 并在解密时使用。


这个问题你那边应该已经解决了吧。能给我代码参考一下吗

针对题目中的两种方式,我将提供详细的解释和示例代码,以展示如何使用 Node.js 实现 AES 128 位 CBC 模式加密,并且会补充如何用 C++ 和 PHP 解密第一种方式生成的数据。

Node.js 示例代码

方式一:不填写 IV

const crypto = require('crypto');

function encryptWithoutIV(key, data) {
  const cipher = crypto.createCipher('aes-128-cbc', key);
  let encrypted = cipher.update(data, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}

const key = '0123456789abcdef'; // 16 bytes
const data = 'Hello World!';
console.log(encryptWithoutIV(key, data));

方式二:填写 IV

const crypto = require('crypto');

function encryptWithIV(key, iv, data) {
  const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
  let encrypted = cipher.update(data, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}

const key = '0123456789abcdef';
const iv = crypto.randomBytes(16).toString('base64');
const data = 'Hello World!';
console.log(encryptWithIV(key, iv, data));

如何用 C++ 或 PHP 解密

C++ 示例

C++ 中可以使用 OpenSSL 库来实现解密。以下是一个简单的示例:

#include <openssl/aes.h>
#include <string>
#include <iostream>

std::string decrypt(const std::string& ciphertext, const std::string& key) {
  unsigned char iv[AES_BLOCK_SIZE] = {0}; // 默认全零
  AES_KEY aesKey;
  AES_set_decrypt_key((unsigned char*)key.c_str(), 128, &aesKey);

  size_t len = ciphertext.size();
  unsigned char* decrypted = new unsigned char[len];
  AES_cbc_encrypt(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), decrypted, len, &aesKey, iv, AES_DECRYPT);
  std::string result(reinterpret_cast<char*>(decrypted), len - AES_BLOCK_SIZE); // 去掉填充部分
  delete[] decrypted;
  return result;
}

int main() {
  std::string ciphertext = "your_encrypted_text";
  std::string key = "0123456789abcdef";
  std::cout << decrypt(ciphertext, key) << std::endl;
  return 0;
}

PHP 示例

PHP 中可以使用 openssl_decrypt 函数来解密:

$key = '0123456789abcdef';
$ciphertext = 'your_encrypted_text';

// 注意: 第一种方式没有IV,所以传递空字符串
$plaintext = openssl_decrypt($ciphertext, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, '');
echo $plaintext;

以上是完整的示例代码以及不同语言中解密的方法。注意在实际应用中,确保安全地处理和传输密钥和初始化向量(IV)。

回到顶部