js做签名及rsa对称加密

简介:js对json数据排序,js使用md5加密,js使用rsa对称加密

最近项目的短信验证码接口被人盗刷,导致公司经济损失。为了解决这个问题我们将短信接口进行参数签名校验以及rsa对称加密。前端js对于加密很不友好,需要自己安装扩展,防止日后忘记,把签名及加密过程记录一下。

1 参数准备

除了表单的实际数据之外,我们还需要一个随机的字符串参数。随机字符串函数:

getRandomString(length) {  
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';  
    return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');  
}

除了随机字符串之外一般还需要加一个时间参数,用于记录当前请求的时间。服务器接收到参数后会校验当前请求是否超时,防止他人盗用请求参数模拟请求。参数组装

let param = {
    is_login:0,
    phone:this.form.phone,
    timestamp:(new Date()).getTime(),
    noncestr:this.getRandomString(8)
};

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]+'&')
});

注意:参数没有做urlencode处理,如果后端服务做了urlencode处理需要使用如下函数处理参数

function urlencode(str) {
  str = encodeURIComponent(str);
  return str.replace(/%20/g, '+');
}

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字符串

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1