我正在建立与已启用ssl的服务器的SSL连接。我的硬件文件系统java密钥库中有一个cacerts文件,我使用keytool& amp;提取证书。我给这个证书文件创建一个SSLSocketfactory来建立ssl连接,这与下面的代码片段工作正常。
我想知道如何直接访问cacerts(java密钥库)文件,然后选择证书并建立ssl连接。现在,我使用我的jar文件将提取的证书打包在类路径中,这不是一个好习惯,因为我希望它从密钥库加载。
下面是我目前如何创建SSLSocketFactory的工作代码片段。
private SSLSocketFactory createSSLFactory() {
KeyStore keyStore = null;
TrustManagerFactory tmf = null;
SSLContext ctx = null;
try {
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream is = null;
is = SSLConnection.class.getResourceAsStream("/" + "my-keystore");
keyStore.load(is, "changeit".toCharArray());
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
ctx = SSLContext.getInstance("TLSv1");
ctx.init(null, tmf.getTrustManagers(), null);
SSLSocketFactory factory = ctx.getSocketFactory();
return factory;
} catch (Exception e) {
// exception handling
}
return null;
}
答案 0 :(得分:2)
在私钥和身份验证证书的情况下,将KeyStore嵌入到JAR文件中没有任何意义。客户端证书应该唯一地标识客户端。它是主机的属性,而不是JAR文件,可以无限复制。允许为多个客户端使用相同的客户端证书是没有意义的。这是对PKI的滥用。
答案 1 :(得分:1)
您可以将密钥库(和信任库)作为系统属性传递给JVM。见这里:https://stackoverflow.com/a/882479/131929
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=gridserver.keystore
-Djavax.net.debug=ssl # very verbose debug
-Djavax.net.ssl.keyStorePassword=$PASS
-Djavax.net.ssl.trustStorePassword=$PASS
然后你可以做
URL url = new URL("https://someurl");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
InputStream inputstream = conn.getInputStream();
答案 2 :(得分:0)
您需要添加一个信任管理器:
SSLSocketFactory factory = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
TrustManagerFactory tmf;
KeyStore ks;
char[] passphrase = "passphrase".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
tmf = TrustManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("testkeys"), passphrase);
kmf.init(ks, passphrase);
tmf.init(ks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
factory = ctx.getSocketFactory();
} catch (Exception e) {
throw new IOException(e.getMessage());
}
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);