感谢原作者袖之欢,点此原文出处。
注:PKCS5Padding 与 PKCS7Padding 基本上是可以通用的。详情见此 What is the difference between PKCS#5 padding and PKCS#7 padding。
AES、DES、Rabbit、RC4、Triple DES 都是对称加密算法,也就是拿到密钥几乎都可以破解密文。不区分公钥、私钥。
如果在网页数据交换中使用对称加密,客户端与服务器端如何传输密钥也会成为一个问题。攻击者只要发现网络中传输的密钥,就能够破解密文。
AES 高级加密标准
AES 全称 Advanced Encryption Standard,是高级加密标准,在密码学中又称为 Rijndael 加密算法。在 PHP 有对应的常量 MCRYPT_RIJNDAEL_128。AES 的密钥长度有 128、192、256 位 3 种长度,可以想见还有 MCRYPT_RIJNDAEL_192、MCRYPT_RIJNDAEL_256。AES 能够比三重 DES 更加快速,也更加安全。
DES 数据加密标准
DES 全称 Data Encryption Standard,是数据加密标准。对明文进行置换实现加密。简单,但不够安全。
Triple DES 三重数据加密算法
Triple DES 全称 Triple Data Encryption Algorithm,简单理解就是执行 3 次 DES 加密,该算法本质上没有对 DES 进行改进,使用 3 条 56 位的密钥对数据进行三次加密。
Crypto-JS 介绍
使用 Crypto-JS 可以非常方便地在 JavaScript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。
基于 Crypto-JS 实现的在线加密解密工具 —— 在线哈希、在线散列 和 在线加密、在线解密。
下面讲述如何使用 Crypto-JS。
Crypto-JS 源码托管在 Google Code,当前版本是 3.1。
Crypto-JS 原网址是 https://code.google.com/p/crypto-js/。文中的英文描述均是原作者所有,Crypto-JS 采用的授权协议跟 MIT 类似,可以在任何场景放心使用。
Crypto-JS 在 NPM 的地址是:https://www.npmjs.com/package/crypto-js。
文章最末附上 Crypto-JS 文件目录结构。
使用 Crypto-JS 进行哈希、散列
- md5
引入 md5.js
<script src="cryptojs/rollups/md5.js"></script>
调用 md5 方法
var str = '123456'; CryptoJS.MD5(str);
- pbkdf2
PBKDF2 is a password-based key derivation function. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can’t be used directly as a cryptographic key, some processing is required.
A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.
引入 pbkdf2.js
<script src="cryptojs/rollups/pbkdf2.js"></script>
调用 pbkdf2 方法
// 官方示例 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 });
- ripemd160
引入 ripemd160.js
<script src="cryptojs/rollups/ripemd160.js"></script>
调用 ripemd160 方法
var str = '123456'; CryptoJS.RIPEMD160(str);
- sha 系列:sha1、sha2、sha3…
sha 具有一系列散列算法
The SHA hash functions were designed by the National Security Agency (NSA). SHA-1 is the most established of the existing SHA hash functions, and it’s used in a variety of security applications and protocols. Though, SHA-1’s collision resistance has been weakening as new attacks are discovered or improved.
SHA-256 is one of the four variants in the SHA-2 set. It isn’t as widely used as SHA-1, though it appears to provide much better security.
SHA-512 is largely identical to SHA-256 but operates on 64-bit words rather than 32.CryptoJS also supports SHA-224 and SHA-384, which are largely identical but truncated versions of SHA-256 and SHA-512 respectively.
SHA-3 is the winner of a five-year competition to select a new cryptographic hash algorithm where 64 competing designs were evaluated.SHA-3 can be configured to output hash lengths of one of 224, 256, 384, or 512 bits. The default is 512 bits.
引入 sha 相关 js
<script src="cryptojs/rollups/sha1.js"></script> <script src="cryptojs/rollups/sha3.js"></script> <script src="cryptojs/rollups/sha224.js"></script> <script src="cryptojs/rollups/sha256.js"></script> <script src="cryptojs/rollups/sha384.js"></script> <script src="cryptojs/rollups/sha512.js"></script>
调用 sha 相关方法
var str = '123456'; CryptoJS.SHA1(str); var str = '123456'; CryptoJS.SHA3(str); // 配置输出的哈希长度 CryptoJS.SHA3(str, {outputLength : 224}); CryptoJS.SHA3(str, {outputLength : 256}); CryptoJS.SHA3(str, {outputLength : 384}); CryptoJS.SHA3(str, {outputLength : 512}); var str = '123456'; CryptoJS.SHA224(str); var str = '123456'; CryptoJS.SHA256(str); var str = '123456'; CryptoJS.SHA284(str); var str = '123456'; CryptoJS.SHA512(str);
- hmac 系列:hmac_md5、hmac_ripemd160、hmac_sha1、hmac_sha3…
引入 hmac 相关 js
<script src="cryptojs/rollups/hmac-sha1.js"> </script> <script src="cryptojs/rollups/hmac-sha3.js"> </script> <script src="cryptojs/rollups/hmac-sha224.js"> </script> <script src="cryptojs/rollups/hmac-sha256.js"> </script> <script src="cryptojs/rollups/hmac-sha384.js"> </script> <script src="cryptojs/rollups/hmac-sha512.js"> </script>
调用 hmac 相关 方法
var str = '123456'; var password = 'password'; // Hmac 相关调用前都增加了 Hmac CryptoJS.HmacMD5(str, password); CryptoJS.HmacRIPEMD160(str, password); CryptoJS.HmacSHA1(str, password); CryptoJS.HmacSHA3(str, password); CryptoJS.HmacSHA224(str, password); CryptoJS.HmacSHA256(str, password); CryptoJS.HmacSHA384(str, password); CryptoJS.HmacSHA512(str, password);
使用 Crypto-JS 进行加密、解密
Crypto-JS 相关 encrypt 函数会并不直接返回字符串,需要调用返回对象的 toString 方法,或者通过 Crypto-JS 转码才能得到真实的结果。
- AES
引入 aes.js
<script src="cryptojs/rollups/aes.js"></script>
调用 CryptoJS.AES
// 官方示例, 每次输出的密文都不一样 CryptoJS.AES.encrypt("Message", "Secret Passphrase"); // 正确用法 var str = '123456'; // 密钥 16 位 var key = '0123456789abcdef'; // 初始向量 initial vector 16 位 var iv = '0123456789abcdef'; // key 和 iv 可以一致 key = CryptoJS.enc.Utf8.parse(key); iv = CryptoJS.enc.Utf8.parse(iv); var encrypted = CryptoJS.AES.encrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为字符串 encrypted = encrypted.toString(); // mode 支持 CBC、CFB、CTR、ECB、OFB, 默认 CBC // padding 支持 Pkcs7、AnsiX923、Iso10126 // 、NoPadding、ZeroPadding, 默认 Pkcs7, 即 Pkcs5 var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为 utf8 字符串 decrypted = CryptoJS.enc.Utf8.stringify(decrypted); // 引入其他加密模式, 填充模式需要引入对应的 js 文件 /* cryptojs/components/mode-cfb-min.js cryptojs/components/mode-ctr-min.js cryptojs/components/mode-ecb-min.js cryptojs/components/mode-ofb-min.js cryptojs/components/pad-ansix923-min.js cryptojs/components/pad-iso10126-min.js cryptojs/components/pad-iso97971-min.js cryptojs/components/pad-nopadding-min.js */
- DES、Triple DES
DES、Triple DES 的调用形式与 AES 一致。
引入 triple.js, DES 和 Triple DES 都定义在 tripledes.js
<script src="cryptojs/rollups/tripledes.js"></script>
调用 CryptoJS.DES, CryptoJS.TripleDES
var str = '123456'; var key = '0123456789abcdef'; var iv = '0123456789abcdef'; key = CryptoJS.enc.Utf8.parse(key); iv = CryptoJS.enc.Utf8.parse(iv); // DES 加密 var encrypted = CryptoJS.DES.encrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为字符串 encrypted = encrypted.toString(); // DES 解密 var decrypted = CryptoJS.DES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为 utf8 字符串 decrypted = CryptoJS.enc.Utf8.stringify(decrypted); // Triple DES 加密 var encrypted = CryptoJS.TripleDES.encrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为字符串 encrypted = encrypted.toString(); // Triple DES 解密 var decrypted = CryptoJS.TripleDES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转换为 utf8 字符串 decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
- Rabbit、RC4
Rabbit、RC4 调用方式一致,不支持 mode、padding。
引入 rabbit.js
<script src="cryptojs/rollups/rabbit.js"></script>
调用 CryptoJS.Rabbit
var str = '123456'; var key = '0123456789abcdef'; var iv = '0123456789abcdef'; key = CryptoJS.enc.Utf8.parse(key); iv = CryptoJS.enc.Utf8.parse(iv); var encrypted = CryptoJS.Rabbit.encrypt(str, key, { iv: iv }); // 转换为字符串 encrypted = encrypted.toString(); var decrypted = CryptoJS.Rabbit.decrypt(encrypted, key, { iv: iv }); // 转换为 utf8 字符串 decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
引入 rc4.js
<script src="cryptojs/rollups/rc4.js"></script>
调用 CryptoJS.RC4
var str = '123456'; var key = '0123456789abcdef'; var iv = '0123456789abcdef'; key = CryptoJS.enc.Utf8.parse(key); iv = CryptoJS.enc.Utf8.parse(iv); var encrypted = CryptoJS.RC4.encrypt(str, key, { iv: iv }); // 转换为字符串 encrypted = encrypted.toString(); var decrypted = CryptoJS.RC4.decrypt(encrypted, key, { iv: iv }); // 转换为 utf8 字符串 decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
Crypto-JS 文件目录结构
- cryptojs
- components
- aes.js
- cipher-core.js
- core.js
- enc-base64.js
- enc-utf16.js
- evpkdf.js
- format-hex.js
- hmac.js
- lib-typedarrays.js
- md5.js
- mode-cfb.js
- mode-ctr.js
- mode-ctr-gladman.js
- mode-ecb.js
- mode-ofb.js
- pad-ansix923.js
- pad-iso10126.js
- pad-iso97971.js
- pad-nopadding.js
- pad-zeropadding.js
- pbkdf2.js
- rabbit.js
- rabbit-legacy.js
- rc4.js
- ripemd160.js
- sha1.js
- sha3.js
- sha224.js
- sha256.js
- sha384.js
- sha512.js
- tripledes.js
- x64-core.js
- rollups
- aes.js
- hmac-md5.js
- hmac-ripemd160.js
- hmac-sha1.js
- hmac-sha3.js
- hmac-sha224.js
- hmac-sha256.js
- hmac-sha384.js
- hmac-sha512.js
- md5.js
- pbkdf2.js
- rabbit.js
- rabbit-legacy.js
- rc4.js
- ripemd160.js
- sha1.js
- sha3.js
- sha224.js
- sha256.js
- sha384.js
- sha512.js
- tripledes.js
- components
cryptojs/components 目录下的所有文件都会对应一个压缩文件,比如 cryptojs/components/aes.js 同时会有一个 cryptojs/components/aes-min.js 文件。
cryptojs/rollups 目录下的所有文件都已经压缩完毕,每个文件都可以单独调用。