方案:使用国密SM3算法实现数字签名
服务端
maven的pom文件引用
<!-- 国密算法支持 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-crypto -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
<version>5.8.26</version>
</dependency>
编写SMUtils工具类
/**
* 生成hmcSm3十六进制摘要
* @param data 数据
* @param key 盐值
*/
public static String sm3Hash(String key,String data){
HMac hMac = SmUtil.hmacSm3(key.getBytes(StandardCharsets.UTF_8));
return hMac.digestHex(data);
}
前端调用接口时,通过请求头传入校验签名,请求头header key自定义 例如:X-HMAC-SM3
@PostMapping(value = "/updateUserInfo")
public AjaxResult updateUserInfo(@RequestBody WhUser whUser){
// 校验用户数据完整性
String hmac = request.getHeader("X-HMAC-SM3");
if (!StringUtils.hasLength(hmac)) {
return AjaxResult.error("校验数据失败,请您刷新重试");
}
if (!SMUtils.sm3Hash(JSON.toJSONString(whUser)).equals(hmac)) {
return AjaxResult.error("校验数据失败,请您刷新重试");
}
}
前端vue使用SM3加密,是否加盐,需要前后端约定
安装依赖包:npm install --save sm-crypto
引入:import { sm3 } from 'sm-crypto';
加盐key:sm3(password.value,16进制的盐值)
//后端给的盐值
strToHex(str: string) {
var hexCharCode = [];
for (var i = 0; i < str.length; i++) {
hexCharCode.push(str.charCodeAt(i).toString(16));
}
return hexCharCode.join('');
}
不加盐key:sm3(password.value)
注意:如果出现签名不一致,主要java端json字符串和前端加密json字符串不一致导致,需要前后都根据属性key进行排序,对空属性进行清除操作即可