* aes加密方法
* @param {string} text 待加密的字符串
* @param {array} key 加密key
*/
function aesEncrypt(text, key) {
const textBytes = aesjs.utils.utf8.toBytes(text); // 把字符串转换成二进制数据
// 这边使用CTR-Counter加密模式,还有其他模式可以选择,具体可以参考aes加密库
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
const encryptedBytes = aesCtr.encrypt(textBytes); // 进行加密
const encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes); // 把二进制数据转成十六进制
return encryptedHex;
}
/**
* aes解密方法
* @param {string} encryptedHex 加密的字符串
* @param {array} key 加密key
*/
function aesDecrypt(encryptedHex, key) {
const encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex); // 把十六进制数据转成二进制
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
const decryptedBytes = aesCtr.decrypt(encryptedBytes); // 进行解密
const decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes); // 把二进制数据转成utf-8字符串
return decryptedText;
}
3、请求登录
/**
* 登陆接口
*/
function submitFn() {
const userName = document.querySelector(“#userName”).value;
const password = document.querySelector(“#password”).value;
const data = {
userName,
password,
};
const text = JSON.stringify(data);
const sendData = aesEncrypt(text, aesKey); // 把要发送的数据转成字符串进行加密
console.log(“发送数据”, text);
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
const encrypted = encrypt.encrypt(aesKey.toString()); // 把aesKey进行非对称加密
const url = “http://localhost:3000/login”;
const params = { id: 0, data: { param1: sendData, param2: encrypted } };
axios({
method: “POST”,
headers: { “content-type”: “application/x-www-form-urlencoded” },
url: url,
data: JSON.stringify(params),
})
.then(function (result) {
const reciveData = aesDecrypt(result.data.data, aesKey); // 用aesKey进行解密
console.log(“接收数据”, reciveData);
})
.catch(function (error) {
console.log(“error”, error);
});
}
-
服务端(Node):
-
- AES库(aes-js):https://github.com/ricmoo/aes-js
-
RSA 库(node-rsa):https://github.com/rzcoder/node-rsa
-
具体代码实现登录接口
1、引用加密库
const http = require(“http”);
const aesjs = require(“aes-js”);
const NodeRSA = require(“node-rsa”);
const rsaKey = new NodeRSA({ b: 1024 }); // key的size为1024位
let aesKey = null; // 用于保存客户端的aesKey
let privateKey = “”; // 用于保存服务端的公钥
rsaKey.setOptions({ encryptionScheme: “pkcs1” }); // 设置加密模式
2、实现 login 接口
http
.createServer((request, response) => {
response.setHeader(“Access-Control-Allow-Origin”, “*”);
response.setHeader(“Access-Control-Allow-Headers”, “Content-Type”);
response.setHeader(“Content-Type”, “application/json”);
switch (request.method) {
case “GET”:
if (request.url === “/getPub”) {
const publicKey = rsaKey.exportKey(“public”);
privateKey = rsaKey.exportKey(“private”);
response.writeHead(200);
response.end(JSON.stringify({ result: true, data: publicKey })); // 把公钥发送给客户端
return;
}
break;
case “POST”:
if (request.url === “/login”) {
let str = “”;
request.on(“data”, function (chunk) {
str += chunk;
});
request.on(“end”, function () {
const params = JSON.parse(str);
const reciveData = decrypt(params.data);
console.log(“reciveData”, reciveData);
// 一系列处理之后
response.writeHead(200);
response.end(
JSON.stringify({
result: true,
data: aesEncrypt(
JSON.stringify({ userId: 123, address: “杭州” }), // 这个数据会被加密
aesKey
),
})
);
});
return;
}
break;
default:
break;
}
response.writeHead(404);
response.end();
})
.listen(3000);
3、加密和解密方法
function decrypt({ param1, param2 }) {
const decrypted = rsaKey.decrypt(param2, “utf8”); // 解密得到aesKey
aesKey = decrypted.split(“,”).map((item) => {
return +item;
});
return aesDecrypt(param1, aesKey);
}
/**
* aes解密方法
* @param {string} encryptedHex 加密的字符串
* @param {array} key 加密key
*/
function aesDecrypt(encryptedHex, key) {
const encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex); // 把十六进制转成二进制数据
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5)); // 这边使用CTR-Counter加密模式,还有其他模式可以选择,具体可以参考aes加密库
const decryptedBytes = aesCtr.decrypt(encryptedBytes); // 进行解密
const decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes); // 把二进制数据转成字符串
return decryptedText;
}
/**
* aes加密方法
* @param {string} text 待加密的字符串
* @param {array} key 加密key
*/
function aesEncrypt(text, key) {
const textBytes = aesjs.utils.utf8.toBytes(text); // 把字符串转成二进制数据
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
const encryptedBytes = aesCtr.encrypt(textBytes); // 加密
const encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes); // 把二进制数据转成十六进制
return encryptedHex;
}
- 完整的示例代码:https://github.com/Pulset/FrontDataEncrypt
演示效果
总结
本文主要介绍了一些前端安全方面的知识和具体加密方案的实现。为了保护客户的隐私数据,不管是 HTTP 还是 HTTPS,都建议密文传输信息,让破解者增加一点攻击难度吧。当然数据加解密也会带来一定性能上的消耗,这个需要各位开发者各自衡量了。
参考文献
看完这篇文章,我奶奶都懂了 https 的原理 (https://www.cnblogs.com/sujing/p/10927569.html)
中间人攻击 (https://zh.wikipedia.org/wiki/%E4%B8%AD%E9%97%B4%E4%BA%BA%E6%94%BB%E5%87%BB)
看完两件事
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

前端面试题是我面试过程中遇到的面试题,每一次面试后我都会复盘总结。我做了一个整理,并且在技术博客找到了专业的解答,大家可以参考下:
由于篇幅有限,只能分享部分面试题,完整版面试题及答案可以【点击我】阅读下载哦~无偿分享给大家
感悟
我做了一个整理,并且在技术博客找到了专业的解答,大家可以参考下:
由于篇幅有限,只能分享部分面试题,完整版面试题及答案可以【点击我】阅读下载哦~无偿分享给大家
感悟
春招面试的后期,运气和实力都很重要,自己也是运气比较好,为了回馈粉丝朋友们(毕竟自己也玩了这么久哈哈哈),整理个人感悟和总结以上。最后祝愿大家能够收获理想offer!!