mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
323 字
1 分钟
crypto-js加密
2026-09-10

Crypto-JS 基础 API 速查#

安装#

npm install crypto-js
const CryptoJS = require('crypto-js');

1. 字符串 ↔ WordArray#

CryptoJS 内部不直接操作字符串,所有加解密都在 WordArray(32-bit word 数组)上进行。

// 字符串 → WordArray(UTF-8 编码)
const wa = CryptoJS.enc.Utf8.parse('Hello');
// WordArray → 字符串
const str = wa.toString(CryptoJS.enc.Utf8); // 'Hello'
// WordArray → 十六进制字符串
wa.toString(); // '48656c6c6f'(默认 hex)
// 十六进制字符串 → WordArray
CryptoJS.enc.Hex.parse('48656c6c6f');

常见编码格式

编码
UTF-8CryptoJS.enc.Utf8CryptoJS.enc.Utf8
HexCryptoJS.enc.HexCryptoJS.enc.Hex
Base64CryptoJS.enc.Base64CryptoJS.enc.Base64
Latin1CryptoJS.enc.Latin1CryptoJS.enc.Latin1

2. AES 加密/解密#

基本用法(字符串输入,自动 PKCS7 填充)#

const ciphertext = CryptoJS.AES.encrypt('明文', '密码').toString();
// ciphertext 是 Base64 字符串
const plaintext = CryptoJS.AES.decrypt(ciphertext, '密码').toString(CryptoJS.enc.Utf8);
// plaintext 是解密后的字符串

高级用法(WordArray 输入,指定模式和填充)#

const key = CryptoJS.enc.Utf8.parse('1234567890abcdef'); // 16 字节 = AES-128
const iv = CryptoJS.enc.Utf8.parse('abcdefghijklmnop'); // 16 字节 IV
const encrypted = CryptoJS.AES.encrypt(message, key, {
iv: iv,
mode: CryptoJS.mode.CBC, // CBC / ECB / CTR / CFB / OFB
padding: CryptoJS.pad.Pkcs7, // Pkcs7 / NoPadding / ZeroPadding
});
// encrypted 是 CipherParams 对象
encrypted.toString(); // Base64 字符串
encrypted.ciphertext.toString(); // Hex 密文(不含 IV)
encrypted.ciphertext.toString(CryptoJS.enc.Base64); // Base64 密文(不含 IV)
// 解密
const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
const plain = decrypted.toString(CryptoJS.enc.Utf8);

⚠️ 常见坑#

// ❌ 错误:传普通对象代替 WordArray
CryptoJS.AES.encrypt({ words: wa.words, sigBytes: wa.sigBytes }, key, opts)
// CryptoJS 不认这个对象,内部当字符串处理 → 结果错误
// ✅ 正确:直接传 WordArray
CryptoJS.AES.encrypt(wa, key, opts)
// ❌ 错误:CipherParams.toString(CryptoJS.enc.Base64)
encrypted.toString(CryptoJS.enc.Base64) // 报错: wordArray.clamp is not a function
// ✅ 正确:用 enc.Base64.stringify()
CryptoJS.enc.Base64.stringify(encrypted.ciphertext)

3. AES 四种模式对比#

模式需要 IV并行特点
ECB相同明文→相同密文,不安全
CBC最常用,需要 IV
CTR计数器模式
CFB流密码模式
// ECB(无 IV)
CryptoJS.AES.encrypt(data, key, { mode: CryptoJS.mode.ECB });
// CBC(需要 IV)
CryptoJS.AES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC });

4. 填充模式#

填充说明
Pkcs7默认,按块大小填充(AES=16字节)
NoPadding不填充,明文必须是块大小的整数倍
ZeroPadding用 0x00 填充到块大小整数倍
Iso979710x80 + 0x00 填充
// 数据正好是 16 字节时用 NoPadding
CryptoJS.AES.encrypt(data16, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});

5. MD5 / SHA 系列#

// MD5
CryptoJS.MD5('hello').toString(); // '5d41402abc4b2a76b9719d911017c592'
// SHA-256
CryptoJS.SHA256('hello').toString();
// SHA-512
CryptoJS.SHA512('hello').toString();
// 也可以传 WordArray
CryptoJS.MD5(CryptoJS.enc.Utf8.parse('hello')).toString();

6. HMAC#

// HMAC-SHA256
CryptoJS.HmacSHA256('message', 'secret-key').toString();
// HMAC-MD5
CryptoJS.HmacMD5('message', 'secret-key').toString();
// 用 WordArray 做 key
const key = CryptoJS.enc.Utf8.parse('my-key');
CryptoJS.HmacSHA256(CryptoJS.enc.Utf8.parse('message'), key).toString();

7. TripleDES#

const key = CryptoJS.enc.Utf8.parse('123456789012345678901234'); // 24 字节
const encrypted = CryptoJS.TripleDES.encrypt('hello', key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});

8. 实用工具#

// Hex ↔ WordArray
const hex = '48656c6c6f';
const wa = CryptoJS.enc.Hex.parse(hex);
wa.toString(CryptoJS.enc.Utf8); // 'Hello'
// Base64 ↔ WordArray
const b64 = 'SGVsbG8=';
const wa2 = CryptoJS.enc.Base64.parse(b64);
wa2.toString(CryptoJS.enc.Utf8); // 'Hello'
// 字节数组 ↔ WordArray
const bytes = [72, 101, 108, 108, 111];
const wa3 = CryptoJS.lib.WordArray.create(bytes);
wa3.toString(CryptoJS.enc.Utf8); // 'Hello'

9. 完整链式加密示例(AES 双层 + XOR)#

const CryptoJS = require('crypto-js');
function xorWords(str, mask) {
const words = [];
for (let i = 0; i < str.length; i += 4) {
let w = 0;
for (let j = 0; j < 4 && i + j < str.length; j++) {
w = (w << 8) | (str.charCodeAt(i + j) ^ mask);
}
words.push(w);
}
return CryptoJS.lib.WordArray.create(words, str.length);
}
const keyA = CryptoJS.enc.Utf8.parse('PIVOT_KEY_A_0001');
const keyB = CryptoJS.enc.Utf8.parse('PIVOT_KEY_B_0001');
// 正向:XOR → AES(keyB) → AES(keyA) → Base64
function encrypt(plain) {
const xored = xorWords(plain, 0x5A);
const enc1 = CryptoJS.AES.encrypt(xored, keyB, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
}).ciphertext;
const enc2 = CryptoJS.AES.encrypt(enc1, keyA, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
}).ciphertext;
return CryptoJS.enc.Base64.stringify(enc2);
}
// 反向:Base64 → AES(keyA) 解密 → AES(keyB) 解密 → XOR
function decrypt(license) {
const raw = CryptoJS.enc.Base64.parse(license);
const dec1 = CryptoJS.AES.decrypt({ ciphertext: raw }, keyA, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
const dec2 = CryptoJS.AES.decrypt({ ciphertext: dec1 }, keyB, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
const xored = dec2.toString(CryptoJS.enc.Latin1);
let result = '';
for (let i = 0; i < xored.length; i++) {
result += String.fromCharCode(xored.charCodeAt(i) ^ 0x5A);
}
return result;
}
// 测试
const lic = encrypt('GRANTED_2026_OK!');
console.log('加密:', lic);
console.log('解密:', decrypt(lic));

10. CipherParams 对象属性#

const encrypted = CryptoJS.AES.encrypt('hello', 'key');
encrypted.toString(); // Base64 密文(含 IV + 密文)
encrypted.ciphertext; // WordArray(仅密文)
encrypted.ciphertext.toString(); // Hex 密文
encrypted.iv; // WordArray(IV,CBC 模式)
encrypted.key; // WordArray(密钥)
encrypted.salt; // WordArray(盐值)
encrypted.algorithm; // 算法对象
encrypted.mode; // 模式
encrypted.padding; // 填充
encrypted.blockSize; // 块大小(字节)
encrypted(formatter); // 自定义输出格式

注意事项#

  1. AES-128 需要 16 字节密钥,AES-256 需要 32 字节密钥
  2. ECB 模式不需要 IV,其他模式需要
  3. NoPadding 时明文必须是 16 字节整数倍
  4. 不要用 {words, sigBytes} 代替 WordArray 对象
  5. CipherParams.toString() 默认输出 Base64,要输出 hex 用 .toString(CryptoJS.enc.Hex)
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

crypto-js加密
https://fatdog.20060113.xyz/posts/crypto-js/
作者
神秘大胖狗
发布于
2026-09-10
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00