package com.sinata.rest.common;
|
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.json.JSONObject;
|
import com.alipay.api.internal.util.StreamUtil;
|
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.lang3.StringUtils;
|
|
import java.io.ByteArrayInputStream;
|
import java.io.InputStream;
|
import java.io.InputStreamReader;
|
import java.io.StringWriter;
|
import java.security.KeyFactory;
|
import java.security.PrivateKey;
|
import java.security.PublicKey;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
import java.util.*;
|
|
public class SignatureUtil {
|
|
public static final String SIGN_TYPE_RSA = "RSA";
|
|
public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
|
|
/**
|
* 私钥加签
|
*
|
* @param content 内容
|
* @param privateKey 私钥
|
* @param charset 编码
|
* @return sgin
|
* @throws Exception 异常
|
*/
|
public static String rsa256Sign(String content, String privateKey,
|
String charset) throws Exception {
|
try {
|
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
|
new ByteArrayInputStream(privateKey.getBytes()));
|
java.security.Signature signature = java.security.Signature
|
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
|
signature.initSign(priKey);
|
if (StrUtil.isEmpty(charset)) {
|
signature.update(content.getBytes());
|
} else {
|
signature.update(content.getBytes(charset));
|
}
|
byte[] signed = signature.sign();
|
return new String(Base64.encodeBase64(signed));
|
} catch (Exception e) {
|
throw new Exception("无效签名;RSAcontent = " + content + "; charset = " + charset, e);
|
}
|
|
}
|
|
|
public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
|
InputStream ins) throws Exception {
|
if (ins == null || StrUtil.isEmpty(algorithm)) {
|
return null;
|
}
|
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
byte[] encodedKey = StreamUtil.readText(ins, "UTF-8").getBytes();
|
encodedKey = Base64.decodeBase64(encodedKey);
|
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
|
}
|
|
/**
|
* 公钥验签
|
*
|
* @param content 内容
|
* @param sign 私钥签名
|
* @param publicKey 公钥
|
* @param charset 编码
|
* @return
|
* @throws Exception
|
*/
|
public static boolean rsa256CheckContent(String content, String sign, String publicKey,
|
String charset) throws Exception {
|
try {
|
PublicKey pubKey = getPublicKeyFromX509("RSA",
|
new ByteArrayInputStream(publicKey.getBytes()));
|
java.security.Signature signature = java.security.Signature
|
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
|
signature.initVerify(pubKey);
|
if (StrUtil.isEmpty(charset)) {
|
signature.update(content.getBytes());
|
} else {
|
signature.update(content.getBytes(charset));
|
}
|
return signature.verify(Base64.decodeBase64(sign.getBytes()));
|
} catch (Exception e) {
|
throw new Exception("无效签名;RSAcontent = " + content + "; charset = " + charset, e);
|
}
|
}
|
|
public static PublicKey getPublicKeyFromX509(String algorithm,
|
InputStream ins) throws Exception {
|
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
StringWriter writer = new StringWriter();
|
StreamUtil.io(new InputStreamReader(ins), writer);
|
byte[] encodedKey = writer.toString().getBytes();
|
encodedKey = Base64.decodeBase64(encodedKey);
|
return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
}
|
|
public static String getAsciiJsonString(JSONObject json) {
|
//将key值单独封装成List
|
List<String> keys = new ArrayList<String>(((Map<String, Object>) json).keySet());
|
//排序
|
Collections.sort(keys);
|
//使用LinkedHashMap记录插入顺序
|
LinkedHashMap<String, Object> linkmap = new LinkedHashMap<String, Object>();
|
//按照key值顺序插入对应的value
|
for (String key : keys) {
|
if (StringUtils.isNotEmpty(key)) {
|
linkmap.put(key, ((Map<String, Object>) json).get(key));
|
}
|
}
|
//将LinkedHashMap转换为JSONObject
|
JSONObject jObject = new JSONObject(true);
|
jObject.putAll(linkmap);
|
//返回JSON字符串
|
return jObject.toString();
|
}
|
|
|
public static String getSignContent(Map<String, String> sortedParams) {
|
StringBuffer content = new StringBuffer();
|
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
Collections.sort(keys);
|
int index = 0;
|
for (int i = 0; i < keys.size(); i++) {
|
String key = keys.get(i);
|
String value = sortedParams.get(key);
|
if (StrUtil.isAllNotEmpty(key, value)) {
|
content.append((index == 0 ? "" : "&") + key + "=" + value);
|
index++;
|
}
|
}
|
return content.toString();
|
}
|
}
|