前端请求加密实战经验分享教你如何安全传输数据
请求加密,这次是真的踩坑了
最近在做一个项目,需要对前端发送的请求进行加密处理。本来以为是个简单的事情,结果搞了一整天,最后发现还是得自己动手丰衣足食。
问题来了,数据怎么加密
一开始,我想的是用HTTPS来加密传输的数据。但是后来发现,项目要求不仅仅是传输层的安全,还需要对请求体本身进行加密。也就是说,即使有人能抓到请求包,也看不到实际的内容。
这里我踩了个坑,以为HTTPS就能解决一切问题,结果被产品经理一顿教育,说安全性不够。好吧,那就开始研究如何在前端对请求体进行加密吧。
试了几个方案,都失败了
首先想到的是用Base64编码,毕竟简单方便。但是很快发现,Base64只是编码,不是加密,稍微有点技术的人都能解码出来。这个方案直接被毙掉了。
然后又试了下AES加密,想着AES应该靠谱多了。找了个库,开始写代码:
import CryptoJS from 'crypto-js';
const key = 'my-secret-key';
const data = { name: 'John', age: 30 };
const encryptedData = CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
console.log(encryptedData); // 输出加密后的字符串
这段代码看起来挺好的,但是问题来了。服务端解密的时候,发现总是报错。折腾了半天发现,原来是我把key写死了,每次请求都用同一个key,这样会导致解密失败。
找到了最终解决方案
最后决定,还是用AES加密,但是这次要动态生成key,并且把key一起传给服务端。这样服务端就能用同样的key解密了。
核心代码就这几行:
import CryptoJS from 'crypto-js';
function generateKey() {
return CryptoJS.lib.WordArray.random(16).toString();
}
function encryptData(data, key) {
const encryptedData = CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
return encryptedData;
}
const data = { name: 'John', age: 30 };
const key = generateKey();
const encryptedData = encryptData(data, key);
// 发送请求
fetch('https://jztheme.com/api/endpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Encryption-Key': key
},
body: JSON.stringify({ encryptedData })
})
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.error('Error:', error));
这里的关键点是`generateKey`函数,它会生成一个随机的key。然后在请求头中加上`Encryption-Key`,这样服务端就能拿到这个key,解密请求体。
一些细节和坑
虽然解决了主要问题,但还是有一些小坑需要注意:
- key的长度:AES支持多种长度的key,常见的有128位、192位和256位。如果选错了长度,可能会导致加密失败。
- 服务端解密:服务端也需要用相同的库和方法来解密,否则会出现不兼容的问题。我们用的是Node.js的`crypto`模块,确保两边一致。
- 性能问题:频繁的加密和解密操作会影响性能,特别是数据量大的时候。可以考虑批量处理或者优化算法。
折腾了半天,终于把这个坑填上了。不过说实话,改完后还有一两个小问题,比如偶尔会出现key同步不同步的情况,但无大碍,后续再优化。
总结一下
以上是我踩坑后的总结,如果你有更好的方案欢迎评论区交流。请求加密这个事情看似简单,其实还是有很多细节需要注意的。希望我的经验对你有帮助。
