目录

AES算法(十一) NodeJS 环境中实战

本篇将对 AES 算法在 NodeJS 环境中应用做个简单的实战讲解,因为 NodeJS 提供了内置加密模块 crypto ,提供了绝大多数的加密算法的实现,本篇将基于 crypto 模块来做演示,因为文本长度有限,仅展示核心步骤,如需查看完整实现,请移步源码:https://github.com/aurthurxlc/js-aes-examples

NodeJS 内核中的 crypto 模块提供了各种各样加密算法的 API,该模块需要底层系统提供 OpenSSL 的支持。

本篇仅对其中的 AES 算法做简单的讲解,如想了解 NodeJS 更多的加密算法,可移步官方文档:https://nodejs.org/api/crypto.html

下面就来一一讲解 NodeJS 中 AES 算法加密、解密的核心点,如有看不明白的地方,请先查看一下前面的理论篇章。

AES 加密、解密核心点

1. 首先要引入 crypto 模块

const crypto = require("crypto");

2. 初始化加密函数

const cipher = crypto.createCipheriv(algorithm, key, iv);

初始化加密函数的 algorithm 参数用于指定加密所使用的算法,例如 AES-128-CBC

  • 其中 AES-128 表示使用 AES 128 位算法,其他可选:AES-192AES-256
  • CBC 表示加密模式,其他可选:CFBOFBCTRGCM(ECB 模式安全性较差,不做推荐)

key 参数接受 Buffer 类型参数,示例如下:

const key = Buffer.from("e43ee68382dc550fbd1d329486febdd4", "hex");

iv 参数接受 Buffer 类型参数,示例如下:

const iv = Buffer.from("ddffc44a93503156abb36e9bbca876f8", "hex");

3. 加密数据

// toHex
let cText = cipher.update(pText, "utf-8", "hex");
cText += cipher.final("hex");

4. 初始化解密函数

const decipher = crypto.createDecipheriv(algorithm, key, iv);

解密函数所用参数应与加密函数相同,否则无法解密。

5. 解密数据

let dText = decipher.update(cText, "hex", "utf-8");
dText += decipher.final("utf8");

6. 输出结果

console.log("key:" + key.toString("hex"));
console.log("iv:" + iv.toString("hex"));
console.log("明文:" + pText);
console.log("加密后数据:" + cText);
console.log("解密密后数据: " + dText);

// 输出如下,跟 Java 输出结果一致
keye43ee68382dc550fbd1d329486febdd4
ivddffc44a93503156abb36e9bbca876f8
明文AES 算法基于 Java 实战演示
加密后数据e8aa678c21aa028988cd74ee2835344519014a4e9365cb8dda7cf24bfe95dfdf0e047cf979587b02500ccad15415b1c3
解密密后数据 AES 算法基于 Java 实战演示

7. 填充模式

上面的函数都不涉及数据填充模式,怎么就结果和 Java 一致了?难道 NodeJS 环境下的 AES 算法解密都不用填充吗?由理论可知,这是不可能的。

翻看 API 文档可知 NodeJS 的加密/解密函数默认是自动填充的,见文档:https://nodejs.org/api/crypto.html#crypto_cipher_setautopadding_autopadding

默认是使用的 PKCS7 填充模式(所以我们未指定填充模式也可以等到跟 Java 相同的加密结果)。

如果需要使用自定义的填充模式,可以使用方法cipher.setAutoPadding(false)禁用自动填充,再自行将数组补齐即可,若自行填充后的数据长度不符合要求,cipher.final()函数将会报错。

crypto 模块 AES 相关核心点说明

crypto 模块常用函数

crypto.createCipheriv(algorithm, key, iv[, options])

  • 创建 Cipher 加密类对象的函数,并不局限于 AES 算法
  • algorithm 参数可选 OpenSSL 算法库支持的所有算法,上文只列举了跟 AES 有关的参数,可用命令 openssl list-cipher-algorithms 查看所支持的算法列表
  • key 、iv 参数仅接受 Buffer 类型参数

crypto.createDecipheriv(algorithm, key, iv[, options])

  • 创建 Decipher 解密类对象的函数,并不局限于 AES 算法,参数同上加密函数

Cipher 类常用函数

cipher.update(data[, inputEncoding][, outputencoding])

  • data
    • 表示添加要加密的数据
    • 具体数据格式可以是 字符串、二进制等
  • inputEncoding(可选)
    • 用于指定 data 的数据类型
    • 可选参数:utf-8binaryascii,默认是binary
    • 如果不指定,data 参数必须是 Buffer 类型
  • outputEncoding(可选)
    • 用于指定 update 函数返回值的类型
    • 可选参数:binarybase64hex,默认是binary
    • 如果不指定 update 函数返回值将是 Buffer 类型

cipher.setAutoPadding([autoPadding])

  • autoPadding(可选)
    • 用于指定是否自动填充数据
    • 可选参数:truefalse
    • 默认为 true,启用自动填充模式,自动填充模式采用的填充方式是:PKCS7

cipher.final([outputEncoding])

  • outputEncoding(可选)
    • 用于指定 final 函数返回值的类型
    • 可选参数:binarybase64hex,默认是 binary
    • 如果不指定 final 函数返回值将是 Buffer 类型

Decipher 常用函数

decipher.update(data[, inputEncoding][, outputencoding])

  • 参数同上加密函数

decipher.setAutoPadding([autoPadding])

  • 参数同上加密函数

decipher.final([outputEncoding])

  • 参数同上加密函数