Netty实现HTTPS客户端
和上一篇文章的代码是一样的,但也做一下记录
SSLContextFactory.java代码
package http2;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.Security;
public final class SslContextFactory {
private static String CLIENT_KEY_STORE = "E:\\javassl2\\sslclientkeys";
private static String CLIENT_TRUST_KEY_STORE = "E:\\javassl2\\sslclienttrust";
private static String CLIENT_KEY_STORE_PASSWORD = "123456";
private static String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";
private static String SERVER_KEY_STORE = "E:\\javassl2\\sslserverkeys";
private static String SERVER_TRUST_KEY_STORE = "E:\\javassl2\\sslservertrust";
private static String SERVER_KEY_STORE_PASSWORD = "123456";
private static String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";
private static final String PROTOCOL = "TLS";
private static final SSLContext SERVER_CONTEXT;
private static final SSLContext CLIENT_CONTEXT;
public SslContextFactory(String type, String key_store, String key_store_password, String trust_key_store, String trust_key_password) {
if ("server".equals(type)) {
SERVER_KEY_STORE = key_store;
SERVER_KEY_STORE_PASSWORD = key_store_password;
SERVER_TRUST_KEY_STORE = trust_key_store;
SERVER_TRUST_KEY_STORE_PASSWORD = trust_key_password;
} else if ("client".equals(type)) {
CLIENT_KEY_STORE = key_store;
CLIENT_KEY_STORE_PASSWORD = key_store_password;
CLIENT_TRUST_KEY_STORE = trust_key_store;
CLIENT_TRUST_KEY_STORE_PASSWORD = trust_key_password;
}
}
static {
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
if (algorithm == null) {
algorithm = "SunX509";
}
SSLContext serverContext;
SSLContext clientContext;
try {
//加载证书库
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(SERVER_KEY_STORE), SERVER_KEY_STORE_PASSWORD.toCharArray());
//加载信任库
KeyStore trustKs = KeyStore.getInstance("JKS");
trustKs.load(new FileInputStream(SERVER_TRUST_KEY_STORE), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
//创建并初始化证书库工厂
String alg = KeyManagerFactory.getDefaultAlgorithm();
// KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
// 创建并初始化信任库工厂
String alg_trust = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg_trust);
tmf.init(trustKs);
// Initialize the SSLContext to work with our key managers.
serverContext = SSLContext.getInstance(PROTOCOL);
/**
* init(KeyManager[],TrustManager[],SecureRandom);
*/
serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (Exception e) {
throw new Error("Failed to initialize the server-side SSLContext", e);
}
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(CLIENT_KEY_STORE), CLIENT_KEY_STORE_PASSWORD.toCharArray());
//加载信任库
KeyStore trustKs = KeyStore.getInstance("JKS");
trustKs.load(new FileInputStream(CLIENT_TRUST_KEY_STORE), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
//创建并初始化证书库工厂
String alg = KeyManagerFactory.getDefaultAlgorithm();
// KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
// 创建并初始化信任库工厂
String alg_trust = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg_trust);
tmf.init(trustKs);
/**
* TLS安全套接字
* Returns a SSLContext object that implements the specified secure socket protocol.
*/
clientContext = SSLContext.getInstance(PROTOCOL);
clientContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (Exception e) {
throw new Error("Failed to initialize the client-side SSLContext", e);
}
SERVER_CONTEXT = serverContext;
CLIENT_CONTEXT = clientContext;
}
public static SSLContext getServerContext() {
return SERVER_CONTEXT;
}
public static SSLContext getClientContext() {
return CLIENT_CONTEXT;
}
private SslContextFactory() {
// Unused
}
}
其中main方法是这样的
public static void main(String args[]) throws HttpPostRequestEncoder.ErrorDataEncoderException, InterruptedException {
String url = "https://www.alipay.com";
HttpRequest get = getRequestMethod(null, url, "get");
new Client().run(url, get);
}
请求支付宝的首页,肯定会出异常,因为使用的证书不是支付宝的证书。
报的异常:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 31 more
unable to find valid certification path to requested target
很明显,找不到有效的证书对于这个请求。
==========END==========