退款的微信请求增加使用pem证书的API
This commit is contained in:
parent
9976bf7772
commit
674ae6ffb0
@ -71,5 +71,10 @@
|
|||||||
<version>3.0.2</version>
|
<version>3.0.2</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk16</artifactId>
|
||||||
|
<version>1.46</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@ -1,12 +1,22 @@
|
|||||||
package com.foxinmy.weixin4j.http.weixin;
|
package com.foxinmy.weixin4j.http.weixin;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.KeyStore;
|
import java.security.*;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.HttpClient;
|
import com.foxinmy.weixin4j.http.HttpClient;
|
||||||
@ -29,6 +39,8 @@ import com.foxinmy.weixin4j.logging.InternalLogLevel;
|
|||||||
import com.foxinmy.weixin4j.logging.InternalLogger;
|
import com.foxinmy.weixin4j.logging.InternalLogger;
|
||||||
import com.foxinmy.weixin4j.logging.InternalLoggerFactory;
|
import com.foxinmy.weixin4j.logging.InternalLoggerFactory;
|
||||||
import com.foxinmy.weixin4j.util.Consts;
|
import com.foxinmy.weixin4j.util.Consts;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 负责微信请求的执行
|
* 负责微信请求的执行
|
||||||
@ -56,6 +68,18 @@ public class WeixinRequestExecutor {
|
|||||||
this.httpClient = HttpClientFactory.getInstance(params);
|
this.httpClient = HttpClientFactory.getInstance(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern CERT_PATTERN = Pattern.compile(
|
||||||
|
"-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)+" + // Header
|
||||||
|
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
|
||||||
|
"-+END\\s+.*CERTIFICATE[^-]*-+", // Footer
|
||||||
|
CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
private static final Pattern KEY_PATTERN = Pattern.compile(
|
||||||
|
"-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+" + // Header
|
||||||
|
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
|
||||||
|
"-+END\\s+.*PRIVATE\\s+KEY[^-]*-+", // Footer
|
||||||
|
CASE_INSENSITIVE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post方法执行微信请求
|
* Post方法执行微信请求
|
||||||
*
|
*
|
||||||
@ -250,4 +274,69 @@ public class WeixinRequestExecutor {
|
|||||||
params.setSSLContext(sslContext);
|
params.setSSLContext(sslContext);
|
||||||
return new WeixinRequestExecutor(params);
|
return new WeixinRequestExecutor(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用PEM格式证书创建SSL微信请求对象
|
||||||
|
*
|
||||||
|
* @param pemCertificate
|
||||||
|
* PEM格式证书内容
|
||||||
|
* @param pemPrivateKey
|
||||||
|
* PEM格式证书私钥
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public WeixinRequestExecutor createSSLRequestExecutor(String password, String pemCertificate, String pemPrivateKey) throws WeixinException{
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] certBytes = parseDERFromPEM(pemCertificate);
|
||||||
|
byte[] keyBytes = parseDERFromPEM(pemPrivateKey);
|
||||||
|
|
||||||
|
char[] passwordChars = password.toCharArray();
|
||||||
|
X509Certificate cert = generateCertificateFromDER(certBytes);
|
||||||
|
RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes);
|
||||||
|
|
||||||
|
KeyStore keystore = KeyStore.getInstance("JKS");
|
||||||
|
keystore.load(null);
|
||||||
|
keystore.setCertificateEntry("cert-alias", cert);
|
||||||
|
keystore.setKeyEntry("key-alias", key, passwordChars, new X509Certificate[] {cert});
|
||||||
|
|
||||||
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||||
|
kmf.init(keystore, passwordChars);
|
||||||
|
|
||||||
|
SSLContext context = SSLContext.getInstance("TLS");
|
||||||
|
context.init(kmf.getKeyManagers(), null, new java.security.SecureRandom());
|
||||||
|
|
||||||
|
return createSSLRequestExecutor(context);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new WeixinException("Certificate load error", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] parseDERFromPEM(String data) throws KeyStoreException {
|
||||||
|
Matcher matcher = CERT_PATTERN.matcher(data);
|
||||||
|
String content = "";
|
||||||
|
if(!matcher.find()){
|
||||||
|
matcher = KEY_PATTERN.matcher(data);
|
||||||
|
if(!matcher.find()){
|
||||||
|
throw new KeyStoreException("found no private key or certificate from content:"+ data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content = matcher.group(1);
|
||||||
|
return DatatypeConverter.parseBase64Binary(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
|
||||||
|
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
|
||||||
|
KeyFactory factory = KeyFactory.getInstance("RSA");
|
||||||
|
|
||||||
|
return (RSAPrivateKey)factory.generatePrivate(spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
|
||||||
|
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||||
|
|
||||||
|
return (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(certBytes));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user