从 crypto-js 了解加密-解密知识点

一、开始之前

网站应用中,对敏感的内容进行加密、解密十分常见。本文将探索 crypto-js 库中的加密和解密能力。crypto-js主要专注于对称加密(如 AES、DES)、哈希算法(如 MD5、SHA 等)和流式加密(如 RC4、Rabbit 等)等方面的支持。

二、crypto-js 安装

sh 复制代码
pnpm add crypto-js

三、顶层 api

以下是 crypto-js 提供的顶层 api

sh 复制代码
import cj from 'crypto-js'

console.log("cj", Object.keys(cj))

输出的结果是:

sh 复制代码
[
  'lib',        'enc',           'algo',
  'x64',        'MD5',           'HmacMD5',
  'SHA1',       'HmacSHA1',      'SHA256',
  'HmacSHA256', 'SHA224',        'HmacSHA224',
  'SHA512',     'HmacSHA512',    'SHA384',
  'HmacSHA384', 'SHA3',          'HmacSHA3',
  'RIPEMD160',  'HmacRIPEMD160', 'PBKDF2',
  'EvpKDF',     'mode',          'pad',
  'format',     'kdf',           'AES',
  'DES',        'TripleDES',     'RC4',
  'RC4Drop',    'Rabbit',        'RabbitLegacy',
  'Blowfish'
]

crypto-js 支持众多的 api, 下面对以上各种 api 的部分内容进行解析。

四、lib 核心库

lib 是核心 api 中的库,承担者主要的加密和解密功能,一般不直接使用。

五、enc 指定字符编码模式

ts 复制代码
import cj from "crypto-js";

console.log(Object.keys(cj.enc));

包含以下的 8 个 API:

ts 复制代码
["Hex", "Latin1", "Utf8", "Utf16BE", "Utf16", "Utf16LE", "Base64", "Base64url"];

使用示例(以下示例以常用的 MD5 形式,以及 16 进制和 base64 两种常见的加密形式):

ts 复制代码
import cj from "crypto-js";

const message = "hello world";
const hash = cj.MD5(message).toString(cj.enc.Hex); // 16 进制形式进行编码
console.log(hash); // 5eb63bbbe01eeed093cb22bb8f5acdc3

const hash = cj.MD5(message).toString(cj.enc.Base64); // base64 形式进行编码
console.log(hash); // XrY7u+Ae7tCTyyK7j1rNww==

const hash = cj.MD5(message).toString(cj.enc.Base64url); // base64 url 形式进行编码
console.log(hash); // XrY7u-Ae7tCTyyK7j1rNww

六、algo 算法

ts 复制代码
import cj from "crypto-js";

console.log(Object.keys(cj.algo))[
  ("MD5",
  "SHA1",
  "SHA256",
  "SHA224",
  "SHA512",
  "SHA384",
  "SHA3",
  "RIPEMD160",
  "HMAC",
  "PBKDF2",
  "EvpKDF",
  "AES",
  "DES",
  "TripleDES",
  "RC4",
  "RC4Drop",
  "Rabbit",
  "RabbitLegacy",
  "Blowfish")
];
类型 算法 说明
哈希算法 MD5 (常用) 生成 128 位哈希值,用于校验数据完整性。
SHA1 (常用系列) 生成 160 位哈希值。
SHA256 生成 256 位哈希值。
SHA224 生成 224 位哈希值。
SHA512 生成 512 位哈希值。
SHA384 生成 384 位哈希值。
SHA3 SHA-3 哈希算法。
RIPEMD160 另一种生成 160 位哈希值的算法。
HMAC 基于密钥的哈希消息认证码。
PBKDF2 密码基于密钥派生函数。
EvpKDF 另一种密钥派生函数。
对称加密算法 AES (常用) 高级加密标准,用于对称加密和解密数据。
DES 数据加密标准,较早的对称加密算法。
TripleDES 对 DES 进行多次加密以增加安全性。
流式加密算法 RC4 流式加密算法。
RC4Drop RC4 的变种。
Rabbit 另一种流式加密算法。
RabbitLegacy Rabbit 算法的旧版本。
其他 Blowfish 对称加密算法,用于加密和解密数据。

七、mode 模式

模式 说明
ECB (Electronic Codebook) 将整个明文分成块,每个块独立加密。可能存在安全性问题。
CBC (Cipher Block Chaining) 前一个块的密文作为下一个块的加密向量,提高了安全性。
CFB (Cipher Feedback) 前一个密文块作为密钥加密当前明文块,可按比块更小单位加密。
OFB (Output Feedback) 使用函数产生的密钥流进行异或运算,提供加密流。
CTR (Counter) 使用计数器的值加密,并与明文进行异或运算,提供加密效果。
CTRGladman CTRGladman 模式
ts 复制代码
import cj from "crypto-js";

const mode = cj.mode;
console.log(mode.CBC);
console.log(mode.CFB);
console.log(mode.CTR);
console.log(mode.CTRGladman);
console.log(mode.ECB);
console.log(mode.OFB);

八、pad 天秤模式

填充方式 说明
AnsiX923 在数据末尾填充零字节,最后一个字节表示需要填充的字节数。
Iso10126 在数据末尾填充随机字节,最后一个字节表示需要填充的字节数。
Iso97971 使用 ISO/IEC 9797-1 填充方案,在数据末尾填充 \x80 加上零或多个 \x00 直到块的大小。
NoPadding 不进行任何填充,要求数据长度必须是块大小的整数倍。
Pkcs7 使用 PKCS#7 填充方案,在数据末尾填充字节,字节的值表示需要填充的字节数。
ZeroPadding 在数据末尾填充零字节,直到数据长度满足块大小的整数倍。
ts 复制代码
import cj from "crypto-js";

const a = cj.pad.AnsiX923;
const b = cj.pad.Iso10126;
const c = cj.pad.Iso97971;
const d = cj.pad.NoPadding;
const e = cj.pad.Pkcs7;
const f = cj.pad.ZeroPadding;

九、对称加密

对称加密是一种加密方式,使用相同的密钥(也称为对称密钥)同时对数据进行加密和解密。这意味着使用相同的密钥,发送方对数据进行加密,接收方使用相同的密钥对加密后的数据进行解密。

AES 加密算法

AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,被广泛用于加密和解密数据。它是由美国国家标准技术研究所(NIST)在 2001 年公布的一种加密标准,用来替代之前的 DES(Data Encryption Standard)算法。使用最为常见的算法。按照长度可以分为:128/192/256 位三种。其中 128 使用最为广泛。

  • AES.encrypt
  • AES.decrypt

将 AES 封装成一个类

ts 复制代码
import CryptoJS from "crypto-js";
import Utf8 from "crypto-js/enc-utf8";
import AES from "crypto-js/aes";
import Pkcs7 from "crypto-js/pad-pkcs7";

class AESCipher {
  constructor(key, mode = CryptoJS.mode.ECB, padding = Pkcs7) {
    this.key = Utf8.parse(key);
    this.mode = mode;
    this.padding = padding;
  }

  // 加密函数
  encrypt(plaintext) {
    const encrypted = AES.encrypt(plaintext, this.key, {
      mode: this.mode,
      padding: this.padding,
    }).toString();
    return encrypted;
  }

  // 解密函数(可选)
  decrypt(encryptedText) {
    const decrypted = AES.decrypt(encryptedText, this.key, {
      mode: this.mode,
      padding: this.padding,
    }).toString(Utf8);
    return decrypted;
  }
}
  • 使用
ts 复制代码
import CryptoJS from "crypto-js";
import Utf8 from "crypto-js/enc-utf8";
import AES from "crypto-js/aes";
import Pkcs7 from "crypto-js/pad-pkcs7";

// 使用示例
const key = "ThisIsASecretKey123";
const aesCipher = new AESCipher(key, CryptoJS.mode.ECB, Pkcs7);
const encryptedText = aesCipher.encrypt("Hello, world!");
console.log("Encrypted:", encryptedText);

// 解密示例(如果需要解密)
const decryptedText = aesCipher.decrypt(encryptedText);
console.log("Decrypted:", decryptedText);

DES 算法

DES(Data Encryption Standard,数据加密标准)是一种对称加密算法,最初在 1977 年被美国政府确定为加密标准,但由于其使用 56 位密钥长度(实际上是 64 位中的 8 位用于校验),密钥长度较短,安全性逐渐变弱,因此在现代安全需求下已不再推荐使用。

  • DES.encrypt
  • DES.decrypt

封装成类:

ts 复制代码
import CryptoJS from "crypto-js";
import Utf8 from "crypto-js/enc-utf8";

class DESCipher {
  constructor(key) {
    this.key = Utf8.parse(key);
  }

  // 加密函数
  encrypt(plaintext) {
    const encrypted = CryptoJS.DES.encrypt(plaintext, this.key).toString();
    return encrypted;
  }

  // 解密函数
  decrypt(encryptedText) {
    const decrypted = CryptoJS.DES.decrypt(encryptedText, this.key).toString(
      Utf8
    );
    return decrypted;
  }
}
  • 使用示例
ts 复制代码
// 使用示例
const key = "12345678"; // 这里示范的密钥长度是 8 位
const desCipher = new DESCipher(key);

// 加密示例
const encryptedText = desCipher.encrypt("Hello, world!");
console.log("Encrypted:", encryptedText);

// 解密示例
const decryptedText = desCipher.decrypt(encryptedText);
console.log("Decrypted:", decryptedText);

TripleDES 算法

TripleDES(Triple Data Encryption Standard)是 DES 的一种改进版本,它对 DES 进行了三重加密,以提高安全性。它的密钥长度是 DES 的三倍,即 168 位(56 位 * 3)。

三阶段:

  1. 第一个阶段(Encrypt) :使用第一个密钥对数据进行加密。
  2. 第二个阶段(Decrypt) :使用第二个密钥对加密后的数据进行解密。
  3. 第三个阶段(Encrypt) :使用第三个密钥再次对解密后的数据进行加密。
  • TripleDES.encrypt
  • TripleDES.decrypt

封装成类:

ts 复制代码
import CryptoJS from "crypto-js";
import Utf8 from "crypto-js/enc-utf8";

class TripleDESCipher {
  constructor(key) {
    this.key = Utf8.parse(key);
  }

  // 加密函数
  encrypt(plaintext) {
    const encrypted = CryptoJS.TripleDES.encrypt(
      plaintext,
      this.key
    ).toString();
    return encrypted;
  }

  // 解密函数
  decrypt(encryptedText) {
    const decrypted = CryptoJS.TripleDES.decrypt(
      encryptedText,
      this.key
    ).toString(Utf8);
    return decrypted;
  }
}
  • 使用
ts 复制代码
// 使用示例
const key = "123456789012345678901234"; // 密钥长度为 24 字符(192 位)
const tripleDESCipher = new TripleDESCipher(key);

// 加密示例
const encryptedText = tripleDESCipher.encrypt("Hello, world!");
console.log("Encrypted:", encryptedText);

// 解密示例
const decryptedText = tripleDESCipher.decrypt(encryptedText);
console.log("Decrypted:", decryptedText);

十、MD5 算法

MD5(Message Digest Algorithm 5)是一种常见的哈希算法,用于生成 128 位(16 字节)的哈希值。它通常用于数据完整性校验、密码存储等场景,被设计为单向散列函数,意味着它将任意长度的输入数据转换为固定长度的输出。

md5 基础用法:

ts 复制代码
import cj from "crypto-js";

console.log(cj.MD5("sdf").toString());

注意: MD5 方法调用之后,还需要调用 toString 方法。MD5 方法得到的是一个对象 {words: array, sigBytes: number}。MD5 方法的特点非常简单固定输入有固定的输出。

十一、SHA 系列算法

算法 哈希值长度 特点
SHA-1 160 位(20 字节) 存在碰撞漏洞,不再被认为是安全的哈希算法。
SHA-256 (常用) 256 位(32 字节) 比 SHA-1 更安全,广泛用于数字签名、SSL 证书等领域。
SHA-224 224 位(28 字节) SHA-256 的截断版,用于特定应用场景。
SHA-512 512 位(64 字节) 比 SHA-256 更安全,提供更长的哈希值,适用于敏感的应用。
SHA-384 384 位(48 字节) 提供比 SHA-256 更长的哈希值,适用于高安全性要求的场景。
SHA-3 - 一种与 SHA-2 系列不同的哈希算法,被认为更为安全。
ts 复制代码
import cj from "crypto-js";

console.log(cj.SHA256(123));
console.log(cj.SHA256(123, {}));
console.log(cj.SHA256([123]));
console.log(cj.SHA256(cj.enc.Utf8.parse("Hello, World!")));

SHA256 函数的参数类型,可以是 string | cj.lib.WordArray, 也可接受第二个可选的参数 config 对象。

十二、基于 hash 的 HMAC 算法

算法 哈希函数 哈希值长度 密钥长度要求 特点
HMAC-MD5 MD5 128 位(16 字节) 任意长度 安全性较低,不推荐使用,存在碰撞攻击风险。
HMAC-SHA1 SHA-1 160 位(20 字节) 任意长度 安全性较低,不推荐使用,存在碰撞攻击风险。
HMAC-SHA256 SHA-256 256 位(32 字节) 推荐大于 256 位 安全性高,广泛应用于数字签名、SSL 证书等领域。
HMAC-SHA512 SHA-512 512 位(64 字节) 推荐大于 512 位 安全性更高,适用于对安全性要求极高的场景。

在实际应用中,HMAC-SHA256 是最常用的 HMAC 算法之一。它具有较高的安全性和广泛的应用场景,在数字签名、SSL 证书、API 认证等许多领域都被广泛采用。HMAC-SHA256 提供了 256 位(32 字节)的哈希值长度,适中的长度同时提供了较高的安全性和较快的计算速度,适合大多数安全性要求不是特别高的场景。

以 HmacSHA256 为例:

ts 复制代码
const CryptoJS.HmacSHA256: HmacHasherHelper
(message: string | cj.lib.WordArray, key: string | cj.lib.WordArray) => cj.lib.WordArray

HmacSHA256 可以接受两个参数: message 需要加密,key

十三、其他加密算法

RC4、RC4Drop、Blowfish、Rabbit 等:一些其他的加密算法,用于特定场景的加密和解密。

算法 密钥长度 块大小 安全性 特点
RC4 可变(1-256 字节) 早期加密算法,由于存在严重的安全漏洞,不再推荐使用。
RC4Drop 固定为 128 位(16 字节) 是 RC4 的一个变种,通过舍弃初始几个字节来提高初始输出的随机性。
Blowfish 32-448 位(4-56 字节) 64 位(8 字节) 中等 对称分组密码算法,安全性较高,但因为比较老旧,在某些场景可能不够。
Rabbit 128 位(16 字节) 较高 流密码算法,用于加密通信。在一些应用中,比如 WPA 和蓝牙加密中被使用。

十四、RSA

RSA 算法属于非对称加密算法,其实现通常比较复杂,并不在crypto-js的范畴之内。

十五、小结

本文从 crypto-js 库的角度看 JS 中的各种加密和解密的方法。全局了解 crypto-js 的 api, 其中包含了 enc、algo、mode 和 pad 属性,以及对称加密 AES/DES 等对称加密。hash 散列计算方法 MD5 以及 SHA 系列算法。

相关推荐
2401_857439691 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧6662 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
阿华的代码王国22 分钟前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
web Rookie25 分钟前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust33 分钟前
css:基础
前端·css
帅帅哥的兜兜33 分钟前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
工业甲酰苯胺36 分钟前
C# 单例模式的多种实现
javascript·单例模式·c#
yi碗汤园36 分钟前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称37 分钟前
购物车-多元素组合动画css
前端·css
德育处主任Pro1 小时前
『Django』APIView基于类的用法
后端·python·django