|
@@ -7,9 +7,8 @@ import java.io.InputStream;
|
|
|
import java.io.InputStreamReader;
|
|
import java.io.InputStreamReader;
|
|
|
import java.io.StringWriter;
|
|
import java.io.StringWriter;
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Field;
|
|
|
-import java.security.KeyFactory;
|
|
|
|
|
-import java.security.PrivateKey;
|
|
|
|
|
-import java.security.PublicKey;
|
|
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
|
+import java.security.*;
|
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
import java.security.spec.X509EncodedKeySpec;
|
|
import java.security.spec.X509EncodedKeySpec;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -21,212 +20,246 @@ import java.util.*;
|
|
|
*/
|
|
*/
|
|
|
public class InvokeSignature {
|
|
public class InvokeSignature {
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取所有Fields,包含父类field
|
|
|
|
|
- *
|
|
|
|
|
- * @param clazz clazz
|
|
|
|
|
- * @return list
|
|
|
|
|
- */
|
|
|
|
|
- private static List<Field> getAllFields(Class<?> clazz) {
|
|
|
|
|
- if (!clazz.equals(Object.class)) {
|
|
|
|
|
- List<Field> fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()));
|
|
|
|
|
- List<Field> fields2 = getAllFields(clazz.getSuperclass());
|
|
|
|
|
- if (fields2 != null) {
|
|
|
|
|
- fields.addAll(fields2);
|
|
|
|
|
- }
|
|
|
|
|
- return fields;
|
|
|
|
|
- } else {
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取所有Fields,包含父类field
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param clazz clazz
|
|
|
|
|
+ * @return list
|
|
|
|
|
+ */
|
|
|
|
|
+ private static List<Field> getAllFields(Class<?> clazz) {
|
|
|
|
|
+ if (!clazz.equals(Object.class)) {
|
|
|
|
|
+ List<Field> fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()));
|
|
|
|
|
+ List<Field> fields2 = getAllFields(clazz.getSuperclass());
|
|
|
|
|
+ if (fields2 != null) {
|
|
|
|
|
+ fields.addAll(fields2);
|
|
|
|
|
+ }
|
|
|
|
|
+ return fields;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static PublicKey getPublicKeyFromX509(String algorithm,
|
|
|
|
|
- InputStream ins) throws Exception {
|
|
|
|
|
- KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
|
|
|
|
|
|
|
|
|
- StringWriter writer = new StringWriter();
|
|
|
|
|
- StreamUtil.io(new InputStreamReader(ins), writer);
|
|
|
|
|
|
|
+ private static PublicKey getPublicKeyFromX509(String algorithm,
|
|
|
|
|
+ InputStream ins) throws Exception {
|
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
|
|
|
|
|
|
|
- byte[] encodedKey = writer.toString().getBytes();
|
|
|
|
|
|
|
+ StringWriter writer = new StringWriter();
|
|
|
|
|
+ StreamUtil.io(new InputStreamReader(ins), writer);
|
|
|
|
|
|
|
|
- encodedKey = Base64.decodeBase64(encodedKey);
|
|
|
|
|
|
|
+ byte[] encodedKey = writer.toString().getBytes();
|
|
|
|
|
|
|
|
- return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ encodedKey = Base64.decodeBase64(encodedKey);
|
|
|
|
|
|
|
|
- private static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
|
|
|
|
|
- InputStream ins) throws Exception {
|
|
|
|
|
- if (ins == null || StringUtils.isEmpty(algorithm)) {
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+ return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
|
|
|
|
|
|
+ private static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
|
|
|
|
|
+ InputStream ins) throws Exception {
|
|
|
|
|
+ if (ins == null || StringUtils.isEmpty(algorithm)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- byte[] encodedKey = StreamUtil.readText(ins).getBytes();
|
|
|
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
|
|
|
|
|
|
|
- encodedKey = Base64.decodeBase64(encodedKey);
|
|
|
|
|
|
|
+ byte[] encodedKey = StreamUtil.readText(ins).getBytes();
|
|
|
|
|
|
|
|
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ encodedKey = Base64.decodeBase64(encodedKey);
|
|
|
|
|
|
|
|
- public static String getSignCheckContent(Map<String, String> params) {
|
|
|
|
|
- if (params == null) {
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+ return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- params.remove("sign");
|
|
|
|
|
- params.remove("sign_type");
|
|
|
|
|
|
|
+ public static String getSignCheckContent(Map<String, String> params) {
|
|
|
|
|
+ if (params == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ params.remove("sign");
|
|
|
|
|
+ params.remove("sign_type");
|
|
|
|
|
|
|
|
- StringBuffer content = new StringBuffer();
|
|
|
|
|
- List<String> keys = new ArrayList<>(params.keySet());
|
|
|
|
|
- Collections.sort(keys);
|
|
|
|
|
|
|
+ StringBuffer content = new StringBuffer();
|
|
|
|
|
+ List<String> keys = new ArrayList<>(params.keySet());
|
|
|
|
|
+ Collections.sort(keys);
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < keys.size(); i++) {
|
|
|
|
|
+ String key = keys.get(i);
|
|
|
|
|
+ String value = params.get(key);
|
|
|
|
|
+ if (StringUtils.isNoneEmpty(key, value)) {
|
|
|
|
|
+ content.append((i == 0 ? "" : "&") + key + "=" + value);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for (int i = 0; i < keys.size(); i++) {
|
|
|
|
|
- String key = keys.get(i);
|
|
|
|
|
- String value = params.get(key);
|
|
|
|
|
- if (StringUtils.isNoneEmpty(key, value)) {
|
|
|
|
|
- content.append((i == 0 ? "" : "&") + key + "=" + value);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return content.toString();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return content.toString();
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 验证签名
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param params
|
|
|
|
|
+ * @param publicKey
|
|
|
|
|
+ * @param charset
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean rsaCheck(Map<String, String> params,
|
|
|
|
|
+ String publicKey,
|
|
|
|
|
+ String charset) {
|
|
|
|
|
+ String sign = params.get("sign");
|
|
|
|
|
+ String content = getSignCheckContent(params);
|
|
|
|
|
+
|
|
|
|
|
+ return rsa256CheckContent(content, sign, publicKey, charset);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 验证签名
|
|
|
|
|
- *
|
|
|
|
|
- * @param params
|
|
|
|
|
- * @param publicKey
|
|
|
|
|
- * @param charset
|
|
|
|
|
- * @return
|
|
|
|
|
- */
|
|
|
|
|
- public static boolean rsaCheck(Map<String, String> params,
|
|
|
|
|
- String publicKey,
|
|
|
|
|
|
|
+ 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 (String key : keys) {
|
|
|
|
|
+ String value = sortedParams.get(key);
|
|
|
|
|
+ if (StringUtils.isNoneEmpty(key, value)) {
|
|
|
|
|
+ content.append((index == 0 ? "" : "&") + key + "=" + value);
|
|
|
|
|
+ index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return content.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * rsa内容签名
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param content
|
|
|
|
|
+ * @param privateKey
|
|
|
|
|
+ * @param charset
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String rsaSign(String content,
|
|
|
|
|
+ String privateKey,
|
|
|
String charset) {
|
|
String charset) {
|
|
|
- String sign = params.get("sign");
|
|
|
|
|
- String content = getSignCheckContent(params);
|
|
|
|
|
-
|
|
|
|
|
- return rsa256CheckContent(content, sign, publicKey, charset);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- 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 (String key : keys) {
|
|
|
|
|
- String value = sortedParams.get(key);
|
|
|
|
|
- if (StringUtils.isNoneEmpty(key, value)) {
|
|
|
|
|
- content.append((index == 0 ? "" : "&") + key + "=" + value);
|
|
|
|
|
- index++;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return rsa256Sign(content, privateKey, charset);
|
|
|
}
|
|
}
|
|
|
- return content.toString();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * rsa内容签名
|
|
|
|
|
- *
|
|
|
|
|
- * @param content
|
|
|
|
|
- * @param privateKey
|
|
|
|
|
- * @param charset
|
|
|
|
|
- * @return
|
|
|
|
|
- */
|
|
|
|
|
- public static String rsaSign(String content,
|
|
|
|
|
- String privateKey,
|
|
|
|
|
- String charset) {
|
|
|
|
|
- return rsa256Sign(content, privateKey, charset);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 转换对象为map
|
|
|
|
|
- *
|
|
|
|
|
- * @param object object
|
|
|
|
|
- * @param ignore ignore
|
|
|
|
|
- * @return map
|
|
|
|
|
- */
|
|
|
|
|
- public static Map<String, String> objectToMap(Object object, String... ignore) {
|
|
|
|
|
- Map<String, String> tempMap = new LinkedHashMap<>();
|
|
|
|
|
- for (Field f : getAllFields(object.getClass())) {
|
|
|
|
|
- if (!f.isAccessible()) {
|
|
|
|
|
- f.setAccessible(true);
|
|
|
|
|
- }
|
|
|
|
|
- boolean ig = false;
|
|
|
|
|
- if (ignore != null && ignore.length > 0) {
|
|
|
|
|
- for (String i : ignore) {
|
|
|
|
|
- if (i.equals(f.getName())) {
|
|
|
|
|
- ig = true;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 转换对象为map
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param object object
|
|
|
|
|
+ * @param ignore ignore
|
|
|
|
|
+ * @return map
|
|
|
|
|
+ */
|
|
|
|
|
+ public static Map<String, String> objectToMap(Object object, String... ignore) {
|
|
|
|
|
+ Map<String, String> tempMap = new LinkedHashMap<>();
|
|
|
|
|
+ for (Field f : getAllFields(object.getClass())) {
|
|
|
|
|
+ if (!f.isAccessible()) {
|
|
|
|
|
+ f.setAccessible(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ boolean ig = false;
|
|
|
|
|
+ if (ignore != null && ignore.length > 0) {
|
|
|
|
|
+ for (String i : ignore) {
|
|
|
|
|
+ if (i.equals(f.getName())) {
|
|
|
|
|
+ ig = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ig) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Object o = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ o = f.get(object);
|
|
|
|
|
+ } catch (IllegalArgumentException | IllegalAccessException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ tempMap.put(f.getName(), o == null ? "" : o.toString());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- if (ig) {
|
|
|
|
|
- continue;
|
|
|
|
|
- } else {
|
|
|
|
|
- Object o = null;
|
|
|
|
|
|
|
+ return tempMap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static boolean rsa256CheckContent(String content,
|
|
|
|
|
+ String sign,
|
|
|
|
|
+ String publicKey,
|
|
|
|
|
+ String charset) {
|
|
|
try {
|
|
try {
|
|
|
- o = f.get(object);
|
|
|
|
|
- } catch (IllegalArgumentException | IllegalAccessException e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
|
+ PublicKey pubKey = getPublicKeyFromX509("RSA",
|
|
|
|
|
+ new ByteArrayInputStream(publicKey.getBytes()));
|
|
|
|
|
+
|
|
|
|
|
+ java.security.Signature signature = java.security.Signature
|
|
|
|
|
+ .getInstance("SHA256WithRSA");
|
|
|
|
|
+
|
|
|
|
|
+ signature.initVerify(pubKey);
|
|
|
|
|
+
|
|
|
|
|
+ if (StringUtils.isEmpty(charset)) {
|
|
|
|
|
+ signature.update(content.getBytes());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ signature.update(content.getBytes(charset));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return signature.verify(Base64.decodeBase64(sign.getBytes()));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new RuntimeException(
|
|
|
|
|
+ "RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
|
|
|
}
|
|
}
|
|
|
- tempMap.put(f.getName(), o == null ? "" : o.toString());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return tempMap;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static boolean rsa256CheckContent(String content,
|
|
|
|
|
- String sign,
|
|
|
|
|
- String publicKey,
|
|
|
|
|
- String charset) {
|
|
|
|
|
- try {
|
|
|
|
|
- PublicKey pubKey = getPublicKeyFromX509("RSA",
|
|
|
|
|
- new ByteArrayInputStream(publicKey.getBytes()));
|
|
|
|
|
-
|
|
|
|
|
- java.security.Signature signature = java.security.Signature
|
|
|
|
|
- .getInstance("SHA256WithRSA");
|
|
|
|
|
-
|
|
|
|
|
- signature.initVerify(pubKey);
|
|
|
|
|
-
|
|
|
|
|
- if (StringUtils.isEmpty(charset)) {
|
|
|
|
|
- signature.update(content.getBytes());
|
|
|
|
|
- } else {
|
|
|
|
|
- signature.update(content.getBytes(charset));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return signature.verify(Base64.decodeBase64(sign.getBytes()));
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw new RuntimeException(
|
|
|
|
|
- "RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
|
|
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- private static String rsa256Sign(String content,
|
|
|
|
|
- String privateKey,
|
|
|
|
|
- String charset) {
|
|
|
|
|
|
|
+ private static String rsa256Sign(String content,
|
|
|
|
|
+ String privateKey,
|
|
|
|
|
+ String charset) {
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ PrivateKey priKey = getPrivateKeyFromPKCS8("RSA",
|
|
|
|
|
+ new ByteArrayInputStream(privateKey.getBytes()));
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- PrivateKey priKey = getPrivateKeyFromPKCS8("RSA",
|
|
|
|
|
- new ByteArrayInputStream(privateKey.getBytes()));
|
|
|
|
|
|
|
+ java.security.Signature signature = java.security.Signature
|
|
|
|
|
+ .getInstance("SHA256WithRSA");
|
|
|
|
|
|
|
|
- java.security.Signature signature = java.security.Signature
|
|
|
|
|
- .getInstance("SHA256WithRSA");
|
|
|
|
|
|
|
+ signature.initSign(priKey);
|
|
|
|
|
|
|
|
- signature.initSign(priKey);
|
|
|
|
|
|
|
+ if (StringUtils.isEmpty(charset)) {
|
|
|
|
|
+ signature.update(content.getBytes());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ signature.update(content.getBytes(charset));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (StringUtils.isEmpty(charset)) {
|
|
|
|
|
- signature.update(content.getBytes());
|
|
|
|
|
- } else {
|
|
|
|
|
- signature.update(content.getBytes(charset));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ byte[] signed = signature.sign();
|
|
|
|
|
|
|
|
- byte[] signed = signature.sign();
|
|
|
|
|
|
|
+ return new String(Base64.encodeBase64(signed));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new RuntimeException("RSAcontent = " + content + "; charset = " + charset, e);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return new String(Base64.encodeBase64(signed));
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw new RuntimeException("RSAcontent = " + content + "; charset = " + charset, e);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * SHA-256加密
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input 明文
|
|
|
|
|
+ * @return 密文
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String SHA256(String input) {
|
|
|
|
|
+ String result = "";
|
|
|
|
|
+ try {
|
|
|
|
|
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
|
|
|
|
|
+ md.update(input.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
+ byte[] digest = md.digest();
|
|
|
|
|
+ result = bytes2Hex(digest);
|
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将字节数组转换为十六进制字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String bytes2Hex(byte[] bts) {
|
|
|
|
|
+ StringBuilder hexSb = new StringBuilder();
|
|
|
|
|
+ for (byte b : bts) {
|
|
|
|
|
+ String hex = Integer.toHexString(0xff & b);
|
|
|
|
|
+ if (hex.length() == 1) hexSb.append('0');
|
|
|
|
|
+ hexSb.append(hex);
|
|
|
|
|
+ }
|
|
|
|
|
+ return hexSb.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|