diff --git a/jsowell-admin/src/main/resources/application.yml b/jsowell-admin/src/main/resources/application.yml index d8319098b..b2ce30400 100644 --- a/jsowell-admin/src/main/resources/application.yml +++ b/jsowell-admin/src/main/resources/application.yml @@ -125,4 +125,9 @@ wulian: getWay: https://api.wl1688.net/iotc/getway name: getSimInfo: api.v2.card.info - WuLianSimRenew: api.v2.order.renew \ No newline at end of file + WuLianSimRenew: api.v2.order.renew + +#高德地图相关 +aMap: + merchantPrivateKey: + aMapPublicKey: \ No newline at end of file diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/amap/util/AMapUtils.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/amap/util/AMapUtils.java new file mode 100644 index 000000000..04f071ec5 --- /dev/null +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/amap/util/AMapUtils.java @@ -0,0 +1,140 @@ +package com.jsowell.thirdparty.amap.util; + +import org.springframework.beans.factory.annotation.Value; + +import java.io.*; +import java.security.*; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.*; + +/** + * 高德地图工具类 + */ +public class AMapUtils { + + @Value("${aMap.merchantPrivateKey}") + private static String MERCHANT_PRIVATE_KEY; + + @Value("${aMap.aMapPublicKey}") + private static String AMAP_PUBLIC_KEY; + + /** + * 使用商家私钥生成签名 + * + * @param paramMap + * @return + * @throws Exception + */ + public static String generateSign(Map paramMap) throws Exception { + //使用商家私钥进行加签,请在高德云店「接入准备及配置」页面生成并获取商家私钥 + String signContent = getSignContent(paramMap); + return getSign(signContent, MERCHANT_PRIVATE_KEY); + } + + /** + * 参数转换为待加签字符串 + * + * @param paramMap 待生成加密sign的参数集合 + */ + private static String getSignContent(Map paramMap) { + StringBuilder content = new StringBuilder(); + List keys = new ArrayList<>(paramMap.keySet()); + // 将参数集合排序 + Collections.sort(keys); + for (int i = 0; i < keys.size(); i++) { + String key = keys.get(i); + //排除不需要参与签名的公共参数 + if ("sign_type".equals(key) || "sign".equals(key) || "need_encrypt".equals(key)) { + continue; + } + String value = paramMap.get(key); + // 拼装所有非空参数 + if (key != null && !"".equalsIgnoreCase(key) && value != null && !"".equalsIgnoreCase(value)) { + content.append(i == 0 ? "" : "&").append(key).append("=").append(value); + } + } + return content.toString(); + } + + /** + * 字符串加签 + * + * @param signContent 待加密的参数字符串 + * @param merchantPrivateKey 商家应用私钥 + * @throws IOException + * @throws GeneralSecurityException + */ + private static String getSign(String signContent, String merchantPrivateKey) throws IOException, GeneralSecurityException { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + byte[] encodedKey = readText(new ByteArrayInputStream(merchantPrivateKey.getBytes())).getBytes(); + encodedKey = Base64.getDecoder().decode(encodedKey); + PrivateKey priKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey)); + + Signature signature = Signature.getInstance("SHA256WithRSA"); + signature.initSign(priKey); + signature.update(signContent.getBytes("UTF-8")); + byte[] signed = signature.sign(); + return new String(Base64.getEncoder().encode(signed)); + } + + private static String readText(InputStream in) throws IOException { + Reader reader = new InputStreamReader(in); + StringWriter writer = new StringWriter(); + + int bufferSize = 4096; + char[] buffer = new char[bufferSize]; + int amount; + while ((amount = reader.read(buffer)) >= 0) { + writer.write(buffer, 0, amount); + } + return writer.toString(); + } + + + // =====================================验签============================================== + + /** + * 使用高德公钥验证签名 + * + * @param paramFromAmap + * @return + * @throws Exception + */ + public static boolean checkSign(Map paramFromAmap) throws Exception { + //使用高德公钥进行验签,请在高德云店「API对接信息」页面直接获取高德公钥 + String signContent = getSignContent(paramFromAmap); + return checkSign(signContent, paramFromAmap.get("sign"), AMAP_PUBLIC_KEY); + } + + /** + * 对加密字符串进行验签 + * + * @param content 待验签内容 + * @param sign 待验证签名 + * @param amapPublicKey 高德公钥 + * @throws IOException + * @throws GeneralSecurityException + */ + private static boolean checkSign(String content, String sign, String amapPublicKey) throws IOException, GeneralSecurityException { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + StringWriter writer = new StringWriter(); + io(new InputStreamReader(new ByteArrayInputStream(amapPublicKey.getBytes())), writer); + byte[] encodedKey = writer.toString().getBytes(); + encodedKey = org.apache.commons.codec.binary.Base64.decodeBase64(encodedKey); + PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); + Signature signature = Signature.getInstance("SHA256WithRSA"); + signature.initVerify(pubKey); + signature.update(content.getBytes("UTF-8")); + return signature.verify(Base64.getDecoder().decode(sign.getBytes())); + } + + public static void io(Reader in, Writer out) throws IOException { + int bufferSize = 4096; + char[] buffer = new char[bufferSize]; + int amount; + while ((amount = in.read(buffer)) >= 0) { + out.write(buffer, 0, amount); + } + } +}