「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」
背景
前一段时间,开发的项目网站,进行了第三方的黑盒测试,测试出几条安全漏洞,其中有一条:登录请求未加密,检测中发现登录请求(例如:用户名、密码、电子邮件地址、社会安全号码等)被发送到服务器的过程中并未采用通讯加密协议或加密。恶意人员可通过数据截包实现网站管理员用户名、密码信息的截获。所以公司决定对登录请求加密处理,于是就用到了下面我们介绍的crypto-js。
crypto-js是什么?
crypto-js 是一个纯 javascript 写的加密算法类库 ,可以非常方便地在 javascript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。而一般密码加密使用AES进行加密。
crypto-js的文档:
官方文档: cryptojs.altervista.org/
githun: github.com/gwjjeff/cry…
npmjs: www.npmjs.com/package/cry…
AES中几种模式的优点和缺点:
ECB模式
优点:
- 简单;
- 有利于并行计算;
- 误差不会被传送;
缺点:
- 不能隐藏明文的模式;
- 可能对明文进行主动攻击;
CBC模式:
优点:
- 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点:
- 不利于并行计算;
- 误差传递;
- 需要初始化向量IV
CFB模式:
优点:
- 隐藏了明文模式;
- 分组密码转化为流模式;
- 可以及时加密传送小于分组的数据;
缺点:
- 不利于并行计算;
- 误差传送:一个明文单元损坏影响多个单元;
- 唯一的IV;
安装
npm install cryptojs
实现 demo
使用crypto-js加密库,实现AES对称加密。AES有多种加密模式,本文仅介绍基于CBC的加密介绍:
加密代码:
function encrypt(data, AES_KEY, AES_IV) { //key,iv:16位的字符串
let key = CryptoJS.enc.Utf8.parse(AES_KEY);
let iv = CryptoJS.enc.Utf8.parse(AES_IV);
return CryptoJS.AES.encrypt(data, key,{
iv : iv,
mode : CryptoJS.mode.CBC,
padding : CryptoJS.pad.Pkcs7
}).toString();
}
参数介绍:
- data: 要加密的字符串。
- AES_KEY: 十六位十六进制数作为密钥。
- AES_IV: 十六位十六进制数作为密钥偏移量。
解密代码:
function cryptoDecrypt( word, AES_IV, AES_KEY) {
const strWord = word.replace(/_/g, '/').replace(/-/g, '+')
const key = CryptoJS.enc.Utf8.parse(AES_KEY)
const iv = CryptoJS.enc.Utf8.parse(AES_IV)
const encryptedHexStr = CryptoJS.enc.Base64.parse(strWord)
const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
let decrypt = ''
decrypt = CryptoJS.AES.decrypt(srcs, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return decrypt.toString(CryptoJS.enc.Utf8).toString()
}
参数介绍:
- word: 要解密的字符串。
- AES_KEY: 密钥。
- AES_IV: 密钥偏移量。
闭坑
加密后的字符串有特殊字符的用encodeURIComponent(URIstring)方法编码后传参就可以了。
- encodeURIComponent: 是一个js函数,该函数可把字符串作为 URI 组件进行编码。
- URIstring: 必传,是一个字符串,含有 URI 组件或其他要编码的文本
- 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:
- _ . ! ~ * ’ ( )。其他字符(比如:;/?:@&=+$,#这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
总结
以上就是我实现crypto-js的AES加密和解密的代码。大家有时间可以去看看文档还有很多加密方式。可以深挖研究。我在这里只是抛砖引玉了。