接口验签

548 阅读1分钟

应用场景

最近写的项目中后端要求在接口请求头中添加一些加密值来进行接口验签,其中用到了HmacSHA256加密

请求头里加appId,stringToSign,timestamp,appId是注册时返回得appId,stringToSign是根据appSecret使用HMAC-SHA256加密时间戳后的字符串,timestamp是时间戳

介绍

项目为了安全考虑,使用HmacSHA256生成签名,由于前端代码本身的公开性,故对于密码以及SK部分使用RSA不对称加密算法进行加密,获取到最后的数组,然后把结果转成16进制的字符串,这就是最后我们需要的结果。

使用

npm install crypto-js
import CryptoJS from "crypto-js";
	// 接口验签
const str =  Date.now().toString(); //转成字符串,否则每次生成的test是一样的
const test = CryptoJS.HmacSHA256(str, "nGsfdjkfjv"); //需要加密的字符串内容和设置的秘钥
const stringToSign = CryptoJS.enc.Hex.stringify(test); //转成16进制的字符串

config.headers = {
	appId: "sO8zrwNPHB4QzCKa",
	stringToSign: stringToSign, //密钥
	timestamp: str,
};

可以使用 www.jsons.cn/allencrypt/ 在线测试

注意

  1. Date.parse(``new Date())毫秒级别的数值被转化为000。可以使用Date.now()
  2. 时间戳是数字,要转成字符串作为参数,当时因为没有转成字符串test的值每次都相同
  3. Header 里 不能传中文字符 编码一下,否则会报错TypeError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest':
//前端js使用 encodeURIComponent 编码
xhr.setRequestHeader("useruselog", encodeURIComponent(msg))  ;
//后端 Java 解码    
useruselog=java.net.URLDecoder.decode(useruselog,"UTF-8");

时间戳

时间戳是指从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。前端开发中常用的js时间戳是毫秒为单位的。获取时间戳的几种方法 参考 tangjiusheng.com/js/403.html

image.png