当前位置:   article > 正文

微信支付V3获取平台证书并解密平台证书详细流程_解密后得到的微信平台证书怎么使用

解密后得到的微信平台证书怎么使用

公司要搞服务号商户卷功能,所以用到了创建商户号接口,有很多数据需要平台证书单独加密,并且图片上传接口返回数据也需要平台证书验签。

   就搞了一下,现在说一下具体细节:

     1:直接点进 敏感信息加密说明

 2 看到微信说加密需要 平台证书

 这里你要搞清楚:商户号证书  和  平台证书不是一个东西,

 商户号证书:是服务商下载的证书

平台证书:微信支付证书

3:现在就去下载微信平台证书,请求接口方式下载

 

 不废话了,直接上获取平台证书代码

   

  1. //获取 获取平台证书列表 测试成功
  2. public static void main(String[] args) throws Exception {
  3. //时间戳
  4. long timestamp = System.currentTimeMillis() / 1000;
  5. //随机字符串(用UUID去掉-就行)
  6. String nonce = IdUtil.fastSimpleUUID().toUpperCase();
  7. String body = "";
  8. //拼接要签名的字符串
  9. PrivateKey privateKey = PayKit.getPrivateKey("这里填商户平台私钥证书");
  10. //拼接要签名的字符串
  11. String orgSignText = "GET\n"
  12. + "/v3/certificates\n"
  13. + timestamp + "\n"
  14. + nonce + "\n"
  15. + body + "\n";
  16. // 生成签名
  17. String sign = RsaKit.encryptByPrivateKey(orgSignText, privateKey);
  18. //要放在HttpHeader中的auth信息
  19. // 获取商户证书序列号 这里填写公钥路径 也就是apiclient_cert.pem这个文件的路径
  20. //证书序列号
  21. X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream("填你的apiclient_cert.pem"));
  22. String serialNo = certificate.getSerialNumber().toString(16).toUpperCase();
  23. String auth = "WECHATPAY2-SHA256-RSA2048 "
  24. + "mchid=\"商户号\",nonce_str=\""
  25. + nonce + "\",timestamp=\"" + timestamp
  26. + "\",serial_no=\"" + serialNo + "\",signature=\"" + sign + "\"";
  27. String url = "https://api.mch.weixin.qq.com/v3/certificates";
  28. HashMap<String, Object> tmap = new HashMap<String, Object>();
  29. tmap.put("Authorization",auth);//tmap.put("token","tonken值");
  30. tmap.put("Accept","application/json");
  31. tmap.put("User-Agent","https://zh.wikipedia.org/wiki/User_agent");
  32. String vmsg= httpGet(url,tmap);//获取请求的返回结果
  33. String rs = HttpClientUtil.sendGetRequest(url, null);
  34. System.out.println("获取平台证书"+vmsg);
  35. }

下面是具体用到的工具类:

  1. public class RsaKit {
  2. /**
  3. * 加密算法RSA
  4. */
  5. private static final String KEY_ALGORITHM = "RSA";
  6. /**
  7. * 私钥签名
  8. *
  9. * @param data 需要加密的数据
  10. * @param privateKey 私钥
  11. * @return 加密后的数据
  12. * @throws Exception 异常信息
  13. */
  14. public static String encryptByPrivateKey(String data, PrivateKey privateKey) throws Exception {
  15. java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
  16. signature.initSign(privateKey);
  17. signature.update(data.getBytes(StandardCharsets.UTF_8));
  18. byte[] signed = signature.sign();
  19. return StrUtil.str(Base64.encode(signed));
  20. }
  21. /**
  22. * 从字符串中加载私钥<br>
  23. * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。
  24. *
  25. * @param privateKeyStr 私钥
  26. * @return {@link PrivateKey}
  27. * @throws Exception 异常信息
  28. */
  29. public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
  30. try {
  31. byte[] buffer = Base64.decode(privateKeyStr);
  32. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  33. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  34. return keyFactory.generatePrivate(keySpec);
  35. } catch (NoSuchAlgorithmException e) {
  36. throw new Exception("无此算法");
  37. } catch (InvalidKeySpecException e) {
  38. throw new Exception("私钥非法");
  39. } catch (NullPointerException e) {
  40. throw new Exception("私钥数据为空");
  41. }
  42. }
  43. /**
  44. * 公钥验证签名
  45. *
  46. * @param data 需要加密的数据
  47. * @param sign 签名
  48. * @param publicKey 公钥
  49. * @return 验证结果
  50. * @throws Exception 异常信息
  51. */
  52. public static boolean checkByPublicKey(String data, String sign, PublicKey publicKey) throws Exception {
  53. java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
  54. signature.initVerify(publicKey);
  55. signature.update(data.getBytes(StandardCharsets.UTF_8));
  56. return signature.verify(Base64.decode(sign.getBytes(StandardCharsets.UTF_8)));
  57. }
  58. }
  1. public class PayKit {
  2. /**
  3. * 获取证书
  4. *
  5. * @param inputStream 证书文件
  6. * @return {@link X509Certificate} 获取证书
  7. */
  8. public static X509Certificate getCertificate(InputStream inputStream) {
  9. try {
  10. CertificateFactory cf = CertificateFactory.getInstance("X509");
  11. X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
  12. cert.checkValidity();
  13. return cert;
  14. } catch (CertificateExpiredException e) {
  15. throw new RuntimeException("证书已过期", e);
  16. } catch (CertificateNotYetValidException e) {
  17. throw new RuntimeException("证书尚未生效", e);
  18. } catch (CertificateException e) {
  19. throw new RuntimeException("无效的证书", e);
  20. }
  21. }
  22. /**
  23. * 简化的UUID,去掉了横线,使用性能更好的 ThreadLocalRandom 生成UUID
  24. *
  25. * @return 简化的 UUID,去掉了横线
  26. */
  27. public static String generateStr() {
  28. return IdUtil.fastSimpleUUID();
  29. }
  30. /**
  31. * 构造签名串
  32. *
  33. * @param method {@link RequestMethod} GET,POST,PUT等
  34. * @param url 请求接口 /v3/certificates
  35. * @param timestamp 获取发起请求时的系统当前时间戳
  36. * @param nonceStr 随机字符串
  37. * @param body 请求报文主体
  38. * @return 待签名字符串
  39. */
  40. public static String buildSignMessage(String method, String url, String timestamp, String nonceStr, String body) {
  41. ArrayList<String> arrayList = new ArrayList<>();
  42. arrayList.add(method);
  43. arrayList.add(url);
  44. arrayList.add(String.valueOf(timestamp));
  45. arrayList.add(nonceStr);
  46. arrayList.add(body);
  47. return buildSignMessage(arrayList);
  48. }
  49. /**
  50. * 构造签名串
  51. *
  52. * @param signMessage 待签名的参数
  53. * @return 构造后带待签名串
  54. */
  55. public static String buildSignMessage(ArrayList<String> signMessage) {
  56. if (signMessage == null || signMessage.size() <= 0) {
  57. return null;
  58. }
  59. StringBuilder sbf = new StringBuilder();
  60. for (String str : signMessage) {
  61. sbf.append(str).append("\n");
  62. }
  63. System.out.println("待签名字符串内容:" + sbf.toString());
  64. System.out.println("待签名字符串长度:" + sbf.toString().length());
  65. return sbf.toString();
  66. }
  67. /**
  68. * v3 接口创建签名
  69. *
  70. * @param signMessage 待签名的参数
  71. * @param keyPath key.pem 证书路径
  72. * @return 生成 v3 签名
  73. * @throws Exception 异常信息
  74. */
  75. public static String createSign(String signMessage, String keyPath) throws Exception {
  76. if (StrUtil.isEmpty(signMessage)) {
  77. return null;
  78. }
  79. // 获取商户私钥
  80. PrivateKey privateKey = PayKit.getPrivateKey(keyPath);
  81. // 生成签名
  82. return RsaKit.encryptByPrivateKey(signMessage, privateKey);
  83. }
  84. /**
  85. * 获取商户私钥
  86. *
  87. * @param keyPath 商户私钥证书路径
  88. * @return {@link PrivateKey} 商户私钥
  89. * @throws Exception 异常信息
  90. */
  91. public static PrivateKey getPrivateKey(String keyPath) throws Exception {
  92. String originalKey = FileUtil.readUtf8String(keyPath);
  93. String privateKey = originalKey
  94. .replace("-----BEGIN PRIVATE KEY-----", "")
  95. .replace("-----END PRIVATE KEY-----", "")
  96. .replaceAll("\\s+", "");
  97. return RsaKit.loadPrivateKey(privateKey);
  98. }
  99. /**
  100. * 获取授权认证信息
  101. *
  102. * @param mchId 商户号
  103. * @param serialNo 商户API证书序列号
  104. * @param nonceStr 请求随机串
  105. * @param timestamp 时间戳
  106. * @param signature 签名值
  107. * @param authType 认证类型,目前为WECHATPAY2-SHA256-RSA2048
  108. * @return 请求头 Authorization
  109. */
  110. public static String getAuthorization(String mchId, String serialNo, String nonceStr, String timestamp, String signature, String authType) {
  111. Map<String, String> params = new HashMap<>(5);
  112. params.put("mchid", mchId);
  113. params.put("serial_no", serialNo);
  114. params.put("nonce_str", nonceStr);
  115. params.put("timestamp", timestamp);
  116. params.put("signature", signature);
  117. return authType.concat(" ").concat(createLinkString(params, ",", false, true));
  118. }
  119. /**
  120. * @param params 需要排序并参与字符拼接的参数组
  121. * @param encode 是否进行URLEncoder
  122. * @return 拼接后字符串
  123. */
  124. public static String createLinkString(Map<String, String> params, boolean encode) {
  125. return createLinkString(params, "&", encode);
  126. }
  127. /**
  128. * @param params 需要排序并参与字符拼接的参数组
  129. * @param connStr 连接符号
  130. * @param encode 是否进行URLEncoder
  131. * @return 拼接后字符串
  132. */
  133. public static String createLinkString(Map<String, String> params, String connStr, boolean encode) {
  134. return createLinkString(params, connStr, encode, false);
  135. }
  136. public static String createLinkString(Map<String, String> params, String connStr, boolean encode, boolean quotes) {
  137. List<String> keys = new ArrayList<>(params.keySet());
  138. Collections.sort(keys);
  139. StringBuilder content = new StringBuilder();
  140. for (int i = 0; i < keys.size(); i++) {
  141. String key = keys.get(i);
  142. String value = params.get(key);
  143. // 拼接时,不包括最后一个&字符
  144. if (i == keys.size() - 1) {
  145. if (quotes) {
  146. content.append(key).append("=").append('"').append(encode ? urlEncode(value) : value).append('"');
  147. } else {
  148. content.append(key).append("=").append(encode ? urlEncode(value) : value);
  149. }
  150. } else {
  151. if (quotes) {
  152. content.append(key).append("=").append('"').append(encode ? urlEncode(value) : value).append('"').append(connStr);
  153. } else {
  154. content.append(key).append("=").append(encode ? urlEncode(value) : value).append(connStr);
  155. }
  156. }
  157. }
  158. return content.toString();
  159. }
  160. /**
  161. * URL 编码
  162. *
  163. * @param src 需要编码的字符串
  164. * @return 编码后的字符串
  165. */
  166. public static String urlEncode(String src) {
  167. try {
  168. return URLEncoder.encode(src, CharsetUtil.UTF_8).replace("+", "%20");
  169. } catch (UnsupportedEncodingException e) {
  170. e.printStackTrace();
  171. return null;
  172. }
  173. }
  174. /**
  175. * 构造签名串
  176. *
  177. * @param timestamp 应答时间戳
  178. * @param nonceStr 应答随机串
  179. * @param body 应答报文主体
  180. * @return 应答待签名字符串
  181. */
  182. public static String buildSignMessage(String timestamp, String nonceStr, String body) {
  183. ArrayList<String> arrayList = new ArrayList<>();
  184. arrayList.add(timestamp);
  185. arrayList.add(nonceStr);
  186. arrayList.add(body);
  187. return buildSignMessage(arrayList);
  188. }
  189. /**
  190. * 公钥加密
  191. *
  192. * @param data 待加密数据
  193. * @param certificate 平台公钥证书
  194. * @return 加密后的数据
  195. * @throws Exception 异常信息
  196. */
  197. public static String rsaEncryptOAEP(String data, X509Certificate certificate) throws Exception {
  198. try {
  199. Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
  200. cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
  201. byte[] dataByte = data.getBytes(StandardCharsets.UTF_8);
  202. byte[] cipherData = cipher.doFinal(dataByte);
  203. return Base64.encode(cipherData);
  204. } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
  205. throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
  206. } catch (InvalidKeyException e) {
  207. throw new IllegalArgumentException("无效的证书", e);
  208. } catch (IllegalBlockSizeException | BadPaddingException e) {
  209. throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");
  210. }
  211. }
  212. /**
  213. * 私钥解密
  214. *
  215. * @param cipherText 加密字符
  216. * @param privateKey 私钥
  217. * @return 解密后的数据
  218. * @throws Exception 异常信息
  219. */
  220. public static String rsaDecryptOAEP(String cipherText, PrivateKey privateKey) throws Exception {
  221. try {
  222. Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
  223. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  224. byte[] data = Base64.decode(cipherText);
  225. return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
  226. } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
  227. throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
  228. } catch (InvalidKeyException e) {
  229. throw new IllegalArgumentException("无效的私钥", e);
  230. } catch (BadPaddingException | IllegalBlockSizeException e) {
  231. throw new BadPaddingException("解密失败");
  232. }
  233. }
  234. }
  1. public class HttpClientUtil
  2. {
  3. public static final String SunX509 = "SunX509";
  4. public static final String JKS = "JKS";
  5. public static final String PKCS12 = "PKCS12";
  6. public static final String TLS = "TLS";
  7. public static HttpURLConnection getHttpURLConnection(String strUrl)
  8. throws IOException
  9. {
  10. URL url = new URL(strUrl);
  11. HttpURLConnection httpURLConnection = (HttpURLConnection)url
  12. .openConnection();
  13. return httpURLConnection;
  14. }
  15. /**
  16. * 发送HTTP_GET请求
  17. *
  18. * @see 该方法会自动关闭连接,释放资源
  19. * @param reqURL
  20. * 请求地址(含参数)
  21. * @param decodeCharset
  22. * 解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
  23. * @return 远程主机响应正文
  24. */
  25. public static String sendGetRequest(String reqURL, String decodeCharset) {
  26. long responseLength = 0; // 响应长度
  27. String responseContent = null; // 响应内容
  28. HttpClient httpClient = new DefaultHttpClient(); // 创建默认的httpClient实例
  29. HttpGet httpGet = new HttpGet(reqURL); // 创建org.apache.http.client.methods.HttpGet
  30. try {
  31. HttpResponse response = httpClient.execute(httpGet); // 执行GET请求
  32. HttpEntity entity = response.getEntity(); // 获取响应实体
  33. if (null != entity) {
  34. responseLength = entity.getContentLength();
  35. responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset);
  36. EntityUtils.consume(entity); // Consume response content
  37. }
  38. System.out.println("请求地址: " + httpGet.getURI());
  39. System.out.println("响应状态: " + response.getStatusLine());
  40. System.out.println("响应长度: " + responseLength);
  41. System.out.println("响应内容: " + responseContent);
  42. } catch (ClientProtocolException e) {
  43. System.out.println("该异常通常是协议错误导致,比如构造HttpGet对象时传入的协议不对(将'http'写成'htp')或者服务器端返回的内容不符合HTTP协议要求等,堆栈信息如下");
  44. } catch (ParseException e) {
  45. System.out.println(e.getMessage());
  46. } catch (IOException e) {
  47. System.out.println("该异常通常是网络原因引起的,如HTTP服务器未启动等,堆栈信息如下");
  48. } finally {
  49. httpClient.getConnectionManager().shutdown(); // 关闭连接,释放资源
  50. }
  51. return responseContent;
  52. }
  53. /**
  54. * 发送HTTP_POST请求
  55. *
  56. * @see 该方法为
  57. * <code>sendPostRequest(String,String,boolean,String,String)</code>
  58. * 的简化方法
  59. * @see 该方法在对请求数据的编码和响应数据的解码时,所采用的字符集均为UTF-8
  60. * @see 当<code>isEncoder=true</code>时,其会自动对<code>sendData</code>中的[中文][|][
  61. * ]等特殊字符进行<code>URLEncoder.encode(string,"UTF-8")</code>
  62. * @param isEncoder
  63. * 用于指明请求数据是否需要UTF-8编码,true为需要
  64. */
  65. public static String sendPostRequest(String reqURL, String sendData, boolean isEncoder) {
  66. return sendPostRequest(reqURL, sendData, isEncoder, null, null,"application/json");
  67. }
  68. /**
  69. * 发送HTTP_POST请求
  70. *
  71. * @see 该方法会自动关闭连接,释放资源
  72. * @see 当<code>isEncoder=true</code>时,其会自动对<code>sendData</code>中的[中文][|][
  73. * ]等特殊字符进行<code>URLEncoder.encode(string,encodeCharset)</code>
  74. * @param reqURL
  75. * 请求地址
  76. * @param sendData
  77. * 请求参数,若有多个参数则应拼接成param11=value11¶m22=value22¶m33=value33的形式后,
  78. * 传入该参数中
  79. * @param isEncoder
  80. * 请求数据是否需要encodeCharset编码,true为需要
  81. * @param encodeCharset
  82. * 编码字符集,编码请求数据时用之,其为null时默认采用UTF-8解码
  83. * @param decodeCharset
  84. * 解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
  85. * @return 远程主机响应正文
  86. */
  87. public static String sendPostRequest(String reqURL, String sendData, boolean isEncoder, String encodeCharset,
  88. String decodeCharset,String contentType) {
  89. String responseContent = null;
  90. HttpClient httpClient = new DefaultHttpClient();
  91. HttpPost httpPost = new HttpPost(reqURL);
  92. // httpPost.setHeader(HTTP.CONTENT_TYPE,
  93. // "application/x-www-form-urlencoded; charset=UTF-8");
  94. httpPost.setHeader(HTTP.CONTENT_TYPE, contentType);
  95. try {
  96. if (isEncoder) {
  97. httpPost.setEntity(new StringEntity(sendData, encodeCharset == null ? "UTF-8" : encodeCharset));
  98. } else {
  99. httpPost.setEntity(new StringEntity(sendData));
  100. }
  101. // 设置请求超时时间
  102. httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
  103. HttpResponse response = httpClient.execute(httpPost);
  104. HttpEntity entity = response.getEntity();
  105. if (null != entity) {
  106. responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset);
  107. EntityUtils.consume(entity);
  108. }
  109. } catch (Exception e) {
  110. System.out.println("与[" + reqURL + "]通信过程中发生异常,堆栈信息如下");
  111. e.printStackTrace();
  112. } finally {
  113. httpClient.getConnectionManager().shutdown();
  114. }
  115. return responseContent;
  116. }
  117. public static HttpsURLConnection getHttpsURLConnection(String strUrl)
  118. throws IOException
  119. {
  120. URL url = new URL(strUrl);
  121. HttpsURLConnection httpsURLConnection = (HttpsURLConnection)url
  122. .openConnection();
  123. return httpsURLConnection;
  124. }
  125. public static String getURL(String strUrl)
  126. {
  127. if (strUrl != null) {
  128. int indexOf = strUrl.indexOf("?");
  129. if (-1 != indexOf) {
  130. return strUrl.substring(0, indexOf);
  131. }
  132. return strUrl;
  133. }
  134. return strUrl;
  135. }
  136. public static String getQueryString(String strUrl)
  137. {
  138. if (strUrl != null) {
  139. int indexOf = strUrl.indexOf("?");
  140. if (-1 != indexOf) {
  141. return strUrl.substring(indexOf + 1, strUrl.length());
  142. }
  143. return "";
  144. }
  145. return strUrl;
  146. }
  147. public static Map queryString2Map(String queryString)
  148. {
  149. if ((queryString == null) || ("".equals(queryString))) {
  150. return null;
  151. }
  152. Map m = new HashMap();
  153. String[] strArray = queryString.split("&");
  154. for (int index = 0; index < strArray.length; index++) {
  155. String pair = strArray[index];
  156. putMapByPair(pair, m);
  157. }
  158. return m;
  159. }
  160. public static void putMapByPair(String pair, Map m)
  161. {
  162. if ((pair == null) || ("".equals(pair))) {
  163. return;
  164. }
  165. int indexOf = pair.indexOf("=");
  166. if (-1 != indexOf) {
  167. String k = pair.substring(0, indexOf);
  168. String v = pair.substring(indexOf + 1, pair.length());
  169. if ((k != null) && (!"".equals(k))) {
  170. m.put(k, v);
  171. }
  172. } else {
  173. m.put(pair, "");
  174. }
  175. }
  176. public static String bufferedReader2String(BufferedReader reader)
  177. throws IOException
  178. {
  179. StringBuffer buf = new StringBuffer();
  180. String line = null;
  181. while ((line = reader.readLine()) != null) {
  182. buf.append(line);
  183. buf.append("\r\n");
  184. }
  185. return buf.toString();
  186. }
  187. public static void doOutput(OutputStream out, byte[] data, int len)
  188. throws IOException
  189. {
  190. int dataLen = data.length;
  191. int off = 0;
  192. while (off < dataLen) {
  193. if (len >= dataLen) {
  194. out.write(data, off, dataLen);
  195. } else {
  196. out.write(data, off, len);
  197. }
  198. out.flush();
  199. off += len;
  200. dataLen -= len;
  201. }
  202. }
  203. public static SSLContext getSSLContext(FileInputStream trustFileInputStream, String trustPasswd, FileInputStream keyFileInputStream, String keyPasswd)
  204. throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException
  205. {
  206. TrustManagerFactory tmf =
  207. TrustManagerFactory.getInstance("SunX509");
  208. KeyStore trustKeyStore = KeyStore.getInstance("JKS");
  209. trustKeyStore.load(trustFileInputStream,
  210. str2CharArray(trustPasswd));
  211. tmf.init(trustKeyStore);
  212. char[] kp = str2CharArray(keyPasswd);
  213. KeyManagerFactory kmf =
  214. KeyManagerFactory.getInstance("SunX509");
  215. KeyStore ks = KeyStore.getInstance("PKCS12");
  216. ks.load(keyFileInputStream, kp);
  217. kmf.init(ks, kp);
  218. SecureRandom rand = new SecureRandom();
  219. SSLContext ctx = SSLContext.getInstance("TLS");
  220. ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), rand);
  221. return ctx;
  222. }
  223. public static Certificate getCertificate(File cafile)
  224. throws CertificateException, IOException
  225. {
  226. CertificateFactory cf = CertificateFactory.getInstance("X.509");
  227. FileInputStream in = new FileInputStream(cafile);
  228. Certificate cert = cf.generateCertificate(in);
  229. in.close();
  230. return cert;
  231. }
  232. public static char[] str2CharArray(String str)
  233. {
  234. if (str == null) {
  235. return null;
  236. }
  237. return str.toCharArray();
  238. }
  239. public static void storeCACert(Certificate cert, String alias, String password, OutputStream out)
  240. throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
  241. {
  242. KeyStore ks = KeyStore.getInstance("JKS");
  243. ks.load(null, null);
  244. ks.setCertificateEntry(alias, cert);
  245. ks.store(out, str2CharArray(password));
  246. }
  247. public static InputStream String2Inputstream(String str)
  248. {
  249. return new ByteArrayInputStream(str.getBytes());
  250. }
  251. }

返回结果:

这就获取到了微信平台证书,但是要注意,这只是获取到了平台证书加密密文 还要进行解密,直接用微信支付文档里面的解密代码就可以。

 

然后解析出真正的微信证书。

注意这里解密有个问题:解密出现Illegal key size错误

   解决:微信支付V3支付通知JAVA解密出现Illegal key size错误 | 微信开放社区

可以用微信证书去加/解密指定内容:

 好了,结束,希望对你有所帮助!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/598849
推荐阅读
相关标签
  

闽ICP备14008679号