Curve25519加密解密
出于安全性的考虑,在原本明文传输的基础上需要对传输内容进行加密,首先,curve25519是一个不对称加密算法,需要前后端相配合,双方一起使用该加密算法,逻辑如下:
-
前端使用generateKeyPair得到自己的公钥和私钥,用自己前端的公钥去交换后端的公钥
-
后端使用generateKeyPair得到自己的公钥和私钥,将后端的公钥返回给前端,同时,用自己的私钥和前端的公钥生成shareKey
-
前端用前端的私钥和后端的公钥生成前端的shareKey
-
前端用shareKey将请求进行加密,在使用AES进行第二次加密
-
后端首先使用AES进行解密,再使用生成的shareKey对前端的请求进行第二次解密,格式符合要求则,使用shareKey进行加密,然后AES加密,传输给前端
-
前端拿到数据,第一步使用AES进行解密,第二步使用shareKey进行解密
Demo
Demo中需要引入的可以在github上下载: https://github.com/zhengyixun/Curve25519
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
1365
</body>
<script src="index.js"></script>
<script>
window.onload=function(){
// Uint8Array 转字符串
function Uint8ArrayToString(fileData){
var dataString = "";
for (var i = 0; i < fileData.length; i++) {
dataString += String.fromCharCode(fileData[i]);
}
return dataString
}
// 字符串 转 Uint8Array
function stringToUint8Array(str) {
var arr = [];
for (var i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
var tmpUint8Array = new Uint8Array(arr);
return tmpUint8Array
}
//要加密的内容
var msg = stringToUint8Array('asdfd');
console.log(msg);
//从给定的32字节密钥种子生成新密钥对
var seed = axlsign.generateKeyPair(new Uint8Array(32));
var private_key = seed.private; //私钥
var public_key = seed.public; //公钥
//使用私钥对给定消息进行签名并返回签名。 可选的随机数据参数(必须具有64个随机字节)打开哈希分离和随机化,以使签名不确定。
//参数: 私钥 要加密的内容
var signature = axlsign.sign(private_key,msg);
console.log(signature);
//参数: 公钥 加密之前的内容 加密后返回的签名 true 正确 false 错误
var f = axlsign.verify(public_key,msg,signature);
console.log("验证签名: "+f);
//使用私钥对给定消息进行签名,并返回签名消息(与消息副本连接的签名)。
//参数: 私钥 要解密的内容 ,,也可以跟第三个参数随机数
var signedMessage = axlsign.signMessage(private_key,msg);
//解密使用公钥 解密成功返回揭秘之后的内容,解密失败,返回null
//参数: 公钥 加密之后的内容
var openMessage = axlsign.openMessage(public_key,signedMessage);
console.log("加密之前的内容: "+Uint8ArrayToString(openMessage));
//计算shareKey 返回自己的私钥和对等公钥之间的原始共享密钥 结果不应直接用作密钥,而应使用单向函数处理
var shareKey = axlsign.sharedKey(private_key,public_key);
console.log(shareKey)
};
</script>
</html>