公司项目中后端提出新的加密需求,使用rsa算法进行加密传输验证。要求前端通过私钥先将参数进行加密后再拼接到URL后进行提交,后端拿到进行验证。
一、前期准备
- 前端rsa加密的库:jsrsasign.js
- 后端提供的密钥对(类似如下结构,以PKCS#8为例):
-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA6GZN0rQFKRIVaPOz
... (省略。。。) ...
LaLGdd9G63kLg85eldSy55uIAXsvqQIgfSYaliVtSbAgyx1Yfs3hJ+CTpNKzTNv/
Fx80EltYV6k=
-----END PRIVATE KEY-----
- 待加密的字符串:如(’aaa’)
1.1 先补充点rsa加密知识
- rsa算法 —— 非对称密钥
公钥私钥成对,用其中一个加密只能用另一个解密,常用公钥加密私钥解密。
JAVAEE项目中很多时候都需要对核心数据进行加密传输,采用非对称加密算法在前段对数据进行加密,在服务端进行解密是一个不错的方式。而常用的实现是采用RSA非对称加密方法。
具体步骤为:
1、在服务端用密码种子生成密钥对,保存密码种子(一个特定的密码种子,生成特定的密钥对,密码种子确定,密钥对确定)或者直接保存私钥
2、把公钥传到页面
3、页面用JS根据公钥把需要加密的数据进行加密,把加密后的数据传回服务端
4、服务端取出保存的密码种子或者直接保存的私钥,采用私钥对加密字符串进行解密,得到明文
二、正题
此次主要解决的问题是 前端通过使用rsa算法库加密字符串并传递
// 1.页面引入:index.html
<script src="js/lib/jsrsasign-all-min.js"></script>
// 2. 使用密钥加密
var rsa = new RSAKey(); //创建rsa实例
//因为后端提供的是pck#8的密钥对,所以这里使用 KEYUTIL.getKey来解析密钥
// yourPEMKey替换为后端提供的密钥
rsa = KEYUTIL.getKey(yourPEMKey);
// 设定签名以 SHA256 为基准,其他还有sha1等,详见文档
var sig = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
// 初始化
sig.init(rsa)
// 传入带加密字符串
sig.updateString(paramStr)
// 生成密文
var sign = hextob64(sig.sign());
// 对加密后内容进行URI编码
sign=encodeURIComponent(sign)
// 最后拼接参数,提交(类似:http://xxx.xxx.com?a=1&b=2&sign=asqaswf)
var url = api+paramStr+'&sign='+sign;
// ajax提交
this.$http.post(url).then(callback)
注意:
1. 密钥对需要带有‘—–BEGIN PRIVATE KEY—–’以及相应的尾标识
2. 密钥对格式为PCK#8时使用KEYUTIL.getKey(yourPEMKey)
进行解析,而PCK#1则使用rsa.readPrivateKeyFromPEMString
3.sig.sign()
生成的是一串16进制字符串(hexadecimal),通过需要转换为base64位使用,通过jsrsasign的全局方法hextob64()进行转换。文档见jsrsasign的global相关方法
4. 最后根据情况 需要使用encodeURICompoent(sign)
将加密后的密文进行转码,因为一些+号传到后端可能不识别。