我们知道网络通信通常是不安全的,所以涉及到敏感信息的传递一般都要使用加密技术。
aes是一种对称加密算法,js的前后端都有造好的轮子,可以直接使用。下面我们给出一个前端js向后端nodejs发送敏感信息(口令)场景的例程。
具体方案就是:前端在发送敏感信息前,先向后端发送一个加密申请,后端反馈一个requestid和加密参数,并将客户端IP和分配的requestid以及加密参数写入redis,并设置短暂有效时间,前端利用加密参数加密敏感信息,带上requestid一起发送到后端,后端根据requestid和客户端IP查redis并删除redis记录,用获取到加密参数来解密信息。
//前端js部分
$.get("/reqsec",(res)=>{
let upw=$("#upw").val();//假设是发送用户密码
let ekey=CryptoJS.enc.Hex.parse(res.key);
let eiv=CryptoJS.enc.Hex.parse(res.iv);
let enpw=CryptoJS.AES.encrypt(upw, ekey, {
iv: eiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
let enpwstr=enpw.ciphertext.toString();
$.post("/pwsend",{"reqid":res.reqid,"upw":enpwstr},
(obj)=>{ if (obj.code=="200") { alert("信息已收到"); } else { alert("提交失败: "+obj.msg); } },
"json");
})
//后端 express部分处理内容
app.get('/reqsec',(req,res)=>{
let clientip=req.header('x-forwarded-for')?req.header('x-forwarded-for'):req.ip;
let reqid="i_"+moment().format("YYYYMMDDHHmmssSSS")+uuidv4().replace(/-/g, '');//redis中的key带个有特定意义的前缀以和其他key区分
let skey=uuidv4().replace(/-/g, '');//32个16进制字符128位加密密钥
let siv=uuidv4().replace(/-/g, '');//32个16进制字符128位初始化向量
client.set(reqid+clientip,skey+siv).then(val=> {res.json({"reqid":reqid,"key":skey,"iv":siv}); });
client.expire(reqid,5);//设置5秒后失效
});
app.post('/pwsend',urlencodedParser,(req,res)=>{
let obj=req.body;
let clientip=req.header('x-forwarded-for')?req.header('x-forwarded-for'):req.ip;
client.get(obj.reqid+clientip).then(val=>{
if (val==null) { logger.error("reqid错 "); res.json({"code":"401",msg:"reqid错"}); }
else {
res.json({"code":"200","msg":"收到"});
let lk=val.substr(0,32);
let iv=val.substr(32);
client.del(obj.reqid+clientip);
let encryptedHexStr = CryptoJS.enc.Hex.parse(obj.upw);
let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
let depw=CryptoJS.AES.decrypt(srcs, CryptoJS.enc.Hex.parse(lk), {
iv: CryptoJS.enc.Hex.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
let upw=CryptoJS.enc.Utf8.stringify(depw);
dealwith(upw);//拿到敏感信息的后处理
}
});
})
参数中输入128位密钥和初始化向量会使用AES256加密,安全性高,速度也快。