前端ajax请求添加rsa签名
如何使用openssl生成私钥 公钥
http://blog.csdn.net/scape1989/article/details/18959657
教程 :https://github.com/kjur/jsrsasign/wiki/Tutorial-for-Signature-class
文章最后有需要引入的js地址
签名原理是 :
前端使用私钥rsa-sha1签名请求body加密为base64格式的签名
后端base64解密使用公钥rsa-sha1验签
前端代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="jquery-3.0.0.min.js"></script>
<script src="jsrsasign-latest-all-min.js"></script>
<script src="caiqrSign.js"></script>
</head>
<body>
</body>
<script>
var sign = doSign("tangxuelong");
console.log(sign);
$.ajax({
type: 'POST',
url: "http://localhost/product",
beforeSend: function(request) {
request.setRequestHeader("caiqiuNodeSign", sign);
},
// dataType: 'json',
// contentType: "application/json",
success: function(data) {
console.log(data);
},
error: function(xhr, type) {
}
});
</script>
</html>
doSign方法所在的js文件代码:
if (!window.atob) {
var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var table = tableStr.split("");
window.atob = function (base64) {
if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");
base64 = base64.replace(/=/g, "");
var n = base64.length & 3;
if (n === 1) throw new Error("String contains an invalid character");
for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) {
var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A");
var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A");
if ((a | b | c | d) < 0) throw new Error("String contains an invalid character");
bin[bin.length] = ((a << 2) | (b >> 4)) & 255;
bin[bin.length] = ((b << 4) | (c >> 2)) & 255;
bin[bin.length] = ((c << 6) | d) & 255;
};
return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);
};
window.btoa = function (bin) {
for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) {
var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++);
if ((a | b | c) > 255) throw new Error("String contains an invalid character");
base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] +
(isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) +
(isNaN(b + c) ? "=" : table[c & 63]);
}
return base64.join("");
};
}
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null,
str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))
);
}
function base64ToHex(str) {
for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) {
var tmp = bin.charCodeAt(i).toString(16);
if (tmp.length === 1) tmp = "0" + tmp;
hex[hex.length] = tmp;
}
return hex.join(" ");
}
/*签名方法*/
function doSign(str) {
var rsaPrivateKey = '-----BEGIN RSA PRIVATE KEY-----
*这里是pem**-----END RSA PRIVATE KEY-----'; // initialize
var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"});
// initialize for signature generation
sig.init(KEYUTIL.getKey(rsaPrivateKey)); // rsaPrivateKey of RSAKey object
// update data
sig.updateString(str);
//calculate signature
return hexToBase64(sig.sign());
}
nodejs api添加验签
// 该路由使用的中间件
router.use(function timeLog(req, res, next) {
res.set({
'Content-Type': 'application/json; charset=utf8',
'Access-Control-Allow-Origin': '*',
'Accept-Language': 'zh-CN'
});
//这里开始验证签名
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA1');
verify.write(req.body);
verify.end();
const publicKey = `-----BEGIN PUBLIC KEY-----
...公钥
-----END PUBLIC KEY-----`;
console.log(req.header("caiqiuNodeSign"));
const signature = new Buffer(req.header("caiqiuNodeSign"),'base64');
console.log(verify.verify(publicKey, signature));
//这里结束
next();
});
nodejs请求添加签名
/*签名*/
var params = postData+"&caiqr_timestamp="+(Date.now()+"").substr(0,10)+"&caiqr_version=1.1&gzip=0";
console.log(getUrlVars(params));
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
***私钥
-----END RSA PRIVATE KEY-----`;
var crypto = require('crypto');
var sign = crypto.createSign('RSA-SHA1');
sign.write(params);
sign.end();
var caiqrSignature = sign.sign(privateKey, 'base64');
console.log(caiqrSignature);
request.post({
url: requestUrl,
form: getUrlVars(params),
headers:{
"Caiqr-Signature":caiqrSignature
}
}, function (error, response, body) {
try {
var jsondata = JSON.parse(body);
nodeconfig.httpHeadSetting(res);
res.end(JSON.stringify(jsondata));
} catch (e) {
nodeconfig.httpHeadSetting(res);
res.end('{code:100001,resp:["服务器异常"]}');
} finally {
}
});
}
都是官方提供的代码,除了前端ajax的代码比较难找。