最近项目的短信验证码接口被人盗刷,导致公司经济损失。为了解决这个问题我们将短信接口进行参数签名校验以及rsa对称加密。前端js对于加密很不友好,需要自己安装扩展,防止日后忘记,把签名及加密过程记录一下。
1 参数准备
除了表单的实际数据之外,我们还需要一个随机的字符串参数。随机字符串函数:
getRandomString(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
除了随机字符串之外一般还需要加一个时间参数,用于记录当前请求的时间。服务器接收到参数后会校验当前请求是否超时,防止他人盗用请求参数模拟请求。参数组装
2 参数签名
参数签名主要分为排序,拼接排序后的json数据成字符串,拼接加密密钥,最后对拼接的字符串进行加密处理
2.1 对json数据进行排序并将排序后的json拼接成字符串
let keys = Object.keys(params);
keys.sort();
let sign_str = ''
keys.forEach(key => {
sign_str = sign_str + (key+'='+params[key]+'&')
});
2.2 拼接加密密钥
let sercet = '签名加密密钥'
sign_str = sign_str + 'key=' + sercet;
2.3 使用md5加密并将加密后的字符串转大写
js中没有现成的MD5加密函数,但是我们可以使用 js-md5 这个扩展包来进行MD5加密。
2.3.1 安装js-md5
npm install js-md5
2.3.2 引入js-md5包
import md5 from 'js-md5';
2.3.3 md5加密
md5(sign_str).toUpperCase();
完成封装如下:
getSign(params){
let keys = Object.keys(params);
keys.sort();
let sign_str = ''
keys.forEach(key => {
sign_str = sign_str + (key+'='+params[key]+'&')
});
sign_str = sign_str + 'key=' + this.sercet;
return md5(sign_str).toUpperCase();
}
4.rsa对称加密
js本身不提供rsa对称加密函数,我们需要自己安装扩展。网上有很多关于rsa对称加密的扩展包,我个人比较喜欢使用 jsencrypt 这个扩展包,使用起来比较简单。
4.1 安装jsencrypt
npm install jsencrypt
4.2 引入jsencrypt扩展
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
4.3 使用jsencrypt进行rsa对称加密
//rsa对称加密,str_value是待加密字符串
getRSAencry(str_value){
if (typeof a != 'string'){
str_value = JSON.stringify(str_value)
}
let publicKey = 'rsa对称加密的公钥'
let jse = new JSEncrypt();
jse.setPublicKey(publicKey);
return jse.encrypt(str_value)
}
注意:公钥不能包含【-----BEGIN PUBLIC KEY-----】及【-----END PUBLIC KEY-----】
一般后端给前端的公钥都是一个完整的公钥文件,实际上我们只需要公钥的内容部分,而且不需要换行处理
如果需要对请求参数进行rsa对称加密处理可以将所有请求参数转json字符串
领取专属 10元无门槛券
私享最新 技术干货