SHA256WithRSA签名
SignatureUtil
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
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 (StringUtil.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 || StringUtil.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 (StringUtil.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 (StringUtil.areNotEmpty(key, value)) {
content.append((index == 0 ? "" : "&") + key + "=" + value);
index++;
}
}
return content.toString();
}
StreamUtil
import java.io.*;
public class StreamUtil {
private StreamUtil(){}
private static final int DEFAULT_BUFFER_SIZE = 8192;
public static void io(InputStream in, OutputStream out) throws IOException {
io(in, out, -1);
}
public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE;
}
byte[] buffer = new byte[bufferSize];
int amount;
while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
}
public static void io(Reader in, Writer out) throws IOException {
io(in, out, -1);
}
public static void io(Reader in, Writer out, int bufferSize) throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE >> 1;
}
char[] buffer = new char[bufferSize];
int amount;
while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
}
public static OutputStream synchronizedOutputStream(OutputStream out) {
return new SynchronizedOutputStream(out);
}
public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {
return new SynchronizedOutputStream(out, lock);
}
public static String readText(InputStream in) throws IOException {
return readText(in, null, -1);
}
public static String readText(InputStream in, String encoding) throws IOException {
return readText(in, encoding, -1);
}
public static String readText(InputStream in, String encoding, int bufferSize)
throws IOException {
Reader reader = (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in,
encoding);
return readText(reader, bufferSize);
}
public static String readText(Reader reader) throws IOException {
return readText(reader, -1);
}
public static String readText(Reader reader, int bufferSize) throws IOException {
StringWriter writer = new StringWriter();
io(reader, writer, bufferSize);
return writer.toString();
}
private static class SynchronizedOutputStream extends OutputStream {
private OutputStream out;
private Object lock;
SynchronizedOutputStream(OutputStream out) {
this(out, out);
}
SynchronizedOutputStream(OutputStream out, Object lock) {
this.out = out;
this.lock = lock;
}
@Override
public void write(int datum) throws IOException {
synchronized (lock) {
out.write(datum);
}
}
@Override
public void write(byte[] data) throws IOException {
synchronized (lock) {
out.write(data);
}
}
@Override
public void write(byte[] data, int offset, int length) throws IOException {
synchronized (lock) {
out.write(data, offset, length);
}
}
@Override
public void flush() throws IOException {
synchronized (lock) {
out.flush();
}
}
@Override
public void close() throws IOException {
synchronized (lock) {
out.close();
}
}
}
}
StringUtil
public class StringUtil {
private StringUtil() {}
/**
* 检查指定的字符串是否为空。
* <ul>
* <li>SysUtils.isEmpty(null) = true</li>
* <li>SysUtils.isEmpty("") = true</li>
* <li>SysUtils.isEmpty(" ") = true</li>
* <li>SysUtils.isEmpty("abc") = false</li>
* </ul>
*
* @param value 待检查的字符串
* @return true/false
*/
public static boolean isEmpty(String value) {
int strLen;
if (value == null || (strLen = value.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(value.charAt(i)) == false)) {
return false;
}
}
return true;
}
/**
* 检查对象是否为数字型字符串,包含负数开头的。
*/
public static boolean isNumeric(Object obj) {
if (obj == null) {
return false;
}
char[] chars = obj.toString().toCharArray();
int length = chars.length;
if(length < 1) {
return false;
}
int i = 0;
if(length > 1 && chars[0] == '-') {
i = 1;
}
for (; i < length; i++) {
if (!Character.isDigit(chars[i])) {
return false;
}
}
return true;
}
/**
* 检查指定的字符串列表是否不为空。
*/
public static boolean areNotEmpty(String... values) {
boolean result = true;
if (values == null || values.length == 0) {
result = false;
} else {
for (String value : values) {
result &= !isEmpty(value);
}
}
return result;
}
/**
* 把通用字符编码的字符串转化为汉字编码。
*/
public static String unicodeToChinese(String unicode) {
StringBuilder out = new StringBuilder();
if (!isEmpty(unicode)) {
for (int i = 0; i < unicode.length(); i++) {
out.append(unicode.charAt(i));
}
}
return out.toString();
}
/**
* 过滤不可见字符
*/
public static String stripNonValidXMLCharacters(String input) {
if (input == null || ("".equals(input))) {
return "";
}
StringBuilder out = new StringBuilder();
char current;
for (int i = 0; i < input.length(); i++) {
current = input.charAt(i);
if ((current == 0x9) || (current == 0xA) || (current == 0xD)
|| ((current >= 0x20) && (current <= 0xD7FF))
|| ((current >= 0xE000) && (current <= 0xFFFD))
|| ((current >= 0x10000) && (current <= 0x10FFFF))) {
out.append(current);
}
}
return out.toString();
}
public static String leftPad(String str, int size, char padChar) {
if (str == null) {
return null;
} else {
int pads = size - str.length();
if (pads <= 0) {
return str;
} else {
return pads > 8192 ? leftPad(str, size, String.valueOf(padChar)) : padding(pads, padChar).concat(str);
}
}
}
public static String leftPad(String str, int size, String padStr) {
if (str == null) {
return null;
} else {
if (isEmpty(padStr)) {
padStr = " ";
}
int padLen = padStr.length();
int strLen = str.length();
int pads = size - strLen;
if (pads <= 0) {
return str;
} else if (padLen == 1 && pads <= 8192) {
return leftPad(str, size, padStr.charAt(0));
} else if (pads == padLen) {
return padStr.concat(str);
} else if (pads < padLen) {
return padStr.substring(0, pads).concat(str);
} else {
char[] padding = new char[pads];
char[] padChars = padStr.toCharArray();
for(int i = 0; i < pads; ++i) {
padding[i] = padChars[i % padLen];
}
return (new String(padding)).concat(str);
}
}
}
private static String padding(int repeat, char padChar) {
if (repeat < 0) {
throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat);
} else {
char[] buf = new char[repeat];
for(int i = 0; i < buf.length; ++i) {
buf[i] = padChar;
}
return new String(buf);
}
}
}