概要内容
- 什么是对称加密
- 对称加密demo
- 什么是非对称加密
- 非对称加密demo
- 对称加密与非对称加密组合使用
- 介绍一套可行的混合加密方案,怎么应用到接口数据加密中
- Demo源码工程
什么是对称加密
-
定义:
对称密钥算法(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥
-
优点:
算法公开、计算量小、加密速度快、加密效率高,适合对大量数据进行加密的场景。 比如 HLS(HTTP Live Streaming)普通加密场景中,一般会使用 AES-128 对称加密算法对 TS 切片进行加密,以保证多媒体资源安全
-
缺点:
安全性不高,只要拿到秘钥就可以把数据解开
-
对称加密的过程:
发送方使用密钥将明文数据加密成密文,然后发送出去,接收方收到密文后,使用同一个密钥将密文解密成明文读取
-
个人理解:
对称加密就好比一把锁的钥匙,一个密码箱存了东西,如果你有钥匙就可以把密码箱里面的宝贝取走
对称加密demo
this.key = CryptoJS.enc.Utf8.parse("0123456789abcdef");
this.iv = CryptoJS.enc.Utf8.parse("abcdef0123456789");
/**
* AES 加密
* @param iv
* @param key
* @param content 加密数据
* @returns {string}
* @private
*/
__aesEncrypt(iv, key, content) {
let text = CryptoJS.enc.Utf8.parse(JSON.stringify(content));
let encrypted = CryptoJS.AES.encrypt(text, key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString();
},
/**
* AES 解密
* @param iv
* @param key
* @param content 解密数据
* @returns {string}
* @private
*/
__aesDecrypt(iv, key, content) {
let decrypt = CryptoJS.AES.decrypt(content, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
let decryptText = decrypt.toString(CryptoJS.enc.Utf8);
return decryptText.replace(/\"/g, "");
},
什么是非对称加密
-
定义:
非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。 因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法
-
优点:
安全性更高,公钥是公开的,私钥是自己保存的,不需要将私钥提供给别人
-
缺点
加解密速度慢,只适合应对小数据加解密
-
对称加密的过程:
-
个人理解
非对称加密:公钥就好比未锁的密码箱,只能存东西进去然后锁住。秘钥就好比密码箱的钥匙,可以打开秘密箱然后把里面的宝贝取走
-
非对称加密demo
this.rsaEncryptor = new JSEncrypt();
this.rsaEncryptor.setPublicKey(this.rsa_pub_key);
this.rsaDecryptor = new JSEncrypt();
this.rsaDecryptor.setPrivateKey(this.rsa_pri_key);
/**
* RSA 加密
* @param content
* @returns {CipherParams|PromiseLike<ArrayBuffer>}
* @private
*/
__rsaEncrypt(content) {
return this.rsaEncryptor.encrypt(content);
},
/**
* RSA 解密
* @param content
* @returns {WordArray|PromiseLike<ArrayBuffer>}
* @private
*/
__rsaDecrypt(content) {
return this.rsaDecryptor.decrypt(content);
},
对称加密与非对称加密组合使用
现在对称加密和非对称加密的缺点我们都知道了,那就结合对称加密和非对称加密的优点来个demo,思路:针对小数据对称加密的iv和key,采用非对称加密;针对大数据data采用对称加密。
/**
* 混合加密
* @param iv
* @param key
* @param content
* @returns {{data: string, iv: (CipherParams|PromiseLike<ArrayBuffer>), key: (CipherParams|PromiseLike<ArrayBuffer>)}}
* @private
*/
__hybirdEncrypt(iv, key, content) {
const aesEncryptData = this.__aesEncrypt(iv, key, content);
const rsaEncryptIv = this.__rsaEncrypt(iv);
const rsaEncryptKey = this.__rsaEncrypt(key);
return {
iv: rsaEncryptIv,
key: rsaEncryptKey,
data: aesEncryptData,
};
},
/**
* 混合解密
* @param encryptInfo
* @returns {string}
* @private
*/
__hybirdDecrypt(encryptInfo) {
const iv = this.rsaDecryptor.decrypt(encryptInfo.iv);
const key = this.rsaDecryptor.decrypt(encryptInfo.key);
const data = encryptInfo.data;
return this.__aesDecrypt(iv, key, data);
}
介绍一套可行混合加密方案,怎么应用到接口数据加密中。流程图如下:
- 思路如下:
- 第1步:创建一套RSA 公私钥,公钥前端拿着,私钥服务端拿着
- 第2步:前端为每一个网络请求生成RequestID
- 第3步:客户端生成AES Key,然后将RequestID 作为Key,AES Key 作为Value 存内存
- 第4步:客户端用生成的AES Key 加密请求数据Request Data,用RSA公钥对AES Key进行加密,同时把requestID、加密数据、加密AES Key 发送给服务端
- 第5步:服务端用RSA私钥解密被加密的AES Key,然后再用解开的AES Key 对RequestData数据进行解密
- 第6步:服务端用AES Key对响应数据ResposneData加密+RequestID、返回给前端
- 第7步:前端根据服务端返回的RequestID 取出内存的AES key, 用AES key 解密Resposne Data数据,用完后删除内存RequestID 的AES key 数据。
- 最后:前端每次发送请求都创建AES Key 去加密数据,收到服务端响应数据解密用完后,就删除掉内存中的AES Key数据,如此循环就用一套RSA公私钥解决混合加密问题
- 流程图:
Demo源码工程:
最后:
由于对称加密DES安全性已不太强,所以就选择了替代品AES。非常感谢阿宝哥提供的玩转混合加密文章,讲得通俗易懂,让我受益匪浅。最后阿宝哥提到把AES key 存放内存容易让他人搞到AES Key。所以我就去了解Web如何防调试、代码怎么混淆等,下一篇:Web如何防调试
参考文献:
更多相关资料:
以上: 如发现有问题,欢迎留言指出,我及时更正