Crypto-JS 介绍以及一个常见的坑
概述
在无法使用 HTTPS 时,或需要增加前端安全时,用 JS 加密是个可行的方法。Crypto-JS 支持 MD5/SHA-1/SHA-2/SHA-3/HMAC/PBKDF2 等 Hash,以及 AES/DES/Triple DES/Rabbit/RC4/RC4Drop 等 Cipher,可自选 Block Modes 和 Padding。可单独加载某一种模式,有很强的组合性。
地址:https://code.google.com/archive/p/crypto-js/ && https://github.com/brix/crypto-js
MD5
可单独引用 md5.js 。 1
CryptoJS.MD5("test");
PBKDF2
可单独引用 pbkdf2.js 。 1
2
3
4
5
6
7
8
9
10
11
12// 官方示例
var str = '123456';
var salt = CryptoJS.lib.WordArray.random(128/8);
var key128Bits = CryptoJS.PBKDF2(str, salt, { keySize: 128/32 });
var key256Bits = CryptoJS.PBKDF2(str, salt, { keySize: 256/32 });
var key512Bits = CryptoJS.PBKDF2(str, salt, { keySize: 512/32 });
var key512Bits1000Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, {
keySize: 512/32,
iterations: 1000
});
AES
默认是 AES-CBC-Pkcs5(Pkcs7)(其他套件可单独引用),密钥长度随输入的密码长度自动确定(如果使用密码短语则使用 256 位)。
加密:(文题所说的坑在这) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var str = '123456'; // 加密内容
var key = '0123456789abcdef'; // 密钥
var iv = '0123456789abcdef'; // 初始向量,不设置会随机生成(当然也就无法解密了)
key = CryptoJS.enc.Utf8.parse(key); // **注意!如果引用了 jQuery 则需要加 "toString()"**
iv = CryptoJS.enc.Utf8.parse(iv); // **同上,详见 [2]**
var encrypted = CryptoJS.AES.encrypt(str, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// **encrypt()返回的是一个对象!需要:**
encrypted = encrypted.toString();
解密: 1
2
3
4
5
6
7
8var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 转换为 utf8 字符串
decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
其他 Cipher
基本上相同,只是 Rabbit 和 RC4 不支持定义 mode 和 padding。
本文参考了:
[1] JavaScript Crypto-JS 使用手册 https://blog.zhengxianjun.com/2015/05/javascript-crypto-js/