验证签名

package com.cloud7.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import java.io.InputStream;
import java.net.URLDecoder;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.util.*;
import java.util.function.BinaryOperator;

/**
* 签名工具类
*/
public class SignUtil {
private static Logger log = LoggerFactory.getLogger(SignUtil.class);

//使用RSA算法加密、SHA算法签名
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
//证书别名
public static final String ALIAS = "uconsole";
//证书库密码
public static final String STORE_PASSWORD = "uconsoleaa";

public static RSAPublicKey rsaPublicKey;
static{
try {
getPublicKey();
}catch (Exception e){
log.error("获取公钥异常"+e.getMessage());
}

}
/**
* @param params
* 所有的请求参数都会在这里进行排序加密
* @return 验证签名结果
*/
public static boolean verifySign(SortedMap<String, String> params) {
String urlSign = params.get("sign");
// if (urlSign.equals("")) {
// return false;
// }
try {
// 把参数加密
String paramsSign = getParamsSign(params);
//解密sign
return verifyWhenSha1Sign(paramsSign,urlSign);
}catch (Exception e){
log.error("验签失败:"+e.getMessage());
}
return false;
}

// public static void main(String[] args) {
// TreeMap map = new TreeMap();
// String in_sign="CmVZ9ElToqnis6Y9n46GSh9AoW%2FGULTxx8Y%2Bj9SyQuv0RH0xUA2yyyyqcQ2GfPf%2BT%2FUJrBjEz16g7AoK1xvYpF2XhlwSnw3PtxKBlniYjKakAUsc6CQ3T%2Bd6shqLimHTBjIaNHxEAEJdeI%2BzxOfTGzy7TlasR0fySmXb5%2BGO%2B9g%3D";
// String decode_sign = URLDecoder.decode(in_sign);
// System.out.println(URLDecoder.decode(in_sign));
// map.put("sign", decode_sign);
// map.put("postbody", "HeKB9CslDyypING/BZqBfJxhKhBHJ8UUWvnG7ygVSBDqE8YhO3ijMhSEK4b121KLxUQjPUMJbwma4PTYeeUI3A==");
// //map.put("postbody", "HeKB9CslDyypING/BZqBfJxhKhBHJ8UUWvnG7ygVSBDqE8YhO3ijMhSEK4b121KL41SUqtXkrqWotvDW3I618w==");
// map.put("timestamp", "1669798524927");
// System.out.println(verifySign(map));
// }

public static void main(String[] args) throws Exception {
String body=SignAesUtil.encryptAES("{\"userName\":\"lic\",\"password\":\"Lic135.com\",\"code\":\"d8gp\"}");
System.out.println("获取的body为:"+body);
long time= new Date().getTime();
JsonObject object=new JsonObject();
String s=body;
object.addProperty("postbody",s);
object.addProperty("timestamp",time);
System.out.println("获取的json数据为:"+object.toString());

String sign=GetSignUtils.genSign(object.toString());

System.out.println("获取的时间戳为:"+time);
System.out.println("获取的sign为:"+sign);
TreeMap map = new TreeMap();
map.put("sign", sign);
map.put("postbody", body);
map.put("timestamp", time);
System.out.println(verifySign(map));
System.out.println(SignUtil.verifyWhenSha1Sign(object.toString(), sign));


}

/**
* @param params
* 所有的请求参数都会在这里进行排序加密
* @return 得到签名
*/
@SneakyThrows
public static String getParamsSign(SortedMap<String, String> params) {
// 要先去掉 Url 里的 Sign
params.remove("sign");
//移除数组类型参数
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getKey().endsWith("[]")) {
iterator.remove();
}
}
String paramsJsonStr = new ObjectMapper().writeValueAsString(params);
return paramsJsonStr;
// return DigestUtils.md5DigestAsHex(paramsJsonStr.getBytes()).toUpperCase();
}

/**
* 对于使用shal和RSA私钥生成的数字签名进行解密验证
* @param content 原文
* @param sign 加密后的数字签名
* @return 数据的正确与否
* @throws Exception
*/
public static boolean verifyWhenSha1Sign(String content, String sign) throws Exception {
byte[] contentBytes = content.getBytes("utf-8");
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
if(Objects.isNull(rsaPublicKey)){
getPublicKey();
}
signature.initVerify(rsaPublicKey);
signature.update(contentBytes);
return signature.verify(Base64.decodeBase64(sign));
}

/**
* 获取公钥
* @return
* @throws Exception
*/
public static RSAPublicKey getPublicKey() throws Exception {
InputStream stream = SignUtil.class.getClassLoader().getResourceAsStream("key/lc.keystore");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(stream, STORE_PASSWORD.toCharArray());
stream.close();
rsaPublicKey = (RSAPublicKey)ks.getCertificate(ALIAS).getPublicKey();
return rsaPublicKey;
}

/**
* 获取私钥
* @param alias 证书别名
* @param storePw 证书库密码
* @param keyPw 证书密码
* @return
* @throws Exception
*/
private static String getPrivateKey(String alias, String storePw, String keyPw) throws Exception {
InputStream is = SignUtil.class.getClassLoader().getResourceAsStream("D:\\home\\liyin\\licenserver\\licenserver\\src\\test\\java\\com\\cloud7\\utils\\lc.keystore");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(is, storePw.toCharArray());
is.close();
PrivateKey key = (PrivateKey) ks.getKey(alias, keyPw.toCharArray());
String privateKey = new BASE64Encoder().encode(key.getEncoded());
return privateKey;
}

}
posted on 2022-12-01 15:38  groby  阅读(83)  评论(0编辑  收藏  举报