[英]How can my library with built in ssl certificate also allow use with default certs
I am distributing a library jar for internal clients, and the library includes a certificate which it uses to call a service that is also internal to our network. 我正在为内部客户端分发库jar,并且该库包含一个证书,用于调用也是我们网络内部的服务。
The trust manager is set up as follows 信任管理器的设置如下
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keystore = KeyStore.getInstance("JKS");
InputStream keystoreStream =
clazz.getClassLoader().getResourceAsStream("certs.keystore"); // (on classpath)
keystore.load(keystoreStream, "pa55w0rd".toCharArray());
trustManagerFactory.init(keystore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustManagers, null);
SSLSocketFactory socketFact = context.getSocketFactory();
connection.setSSLSocketFactory(socketFact);
All of this works fine except in cases where users need other certificates or the default certificate. 所有这些都可以正常工作,除非用户需要其他证书或默认证书。
I tried this Registering multiple keystores in JVM with no luck (I am having trouble generalizing it for my case) 我试过这个在JVM中注册多个密钥库而没有运气(我在为我的情况推广它时遇到了麻烦)
How can I use my cert and still allow user libraries to use their own certs as well? 我如何使用我的证书并仍允许用户库使用自己的证书?
You are configuring a connection with a custom keystore acting as a truststore ( a certificate of your server that you trust). 您正在配置与充当信任库的自定义密钥库的连接(您信任的服务器的证书)。 You are not overriding the default JVM behaviour, so the rest of the connection that other applications that include your library can make will not be affected.
您没有覆盖默认的JVM行为,因此包含您的库的其他应用程序可以创建的其余连接不会受到影响。
Therefore you do not need a multiple keystore manager, in fact, your code works perfectly. 因此,您不需要多个密钥库管理器,事实上,您的代码完美无缺。
I've attached a full example below using a keystore google.jks
which includes Google's root CA, and a connection using the default JVM truststore. 我在下面使用密钥库
google.jks
附加了一个完整的示例,其中包括Google的根CA和使用默认JVM信任库的连接。 This is the output 这是输出
request("https://www.google.com/", "test/google.jks", "pa55w0rd"); //OK
request("https://www.aragon.es/", "test/google.jks", "pa55w0rd"); // FAIL sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
request("https://www.aragon.es/", null, null); //OK
The problem is not in the code you have attached, so check the following in your code: 问题不在您附加的代码中,因此请在代码中检查以下内容:
The truststore certs.keystore
is really found in your classpath 您可以在类路径中找到truststore
certs.keystore
Truststore settings are not set at JVM level using -Djavax.net.ssl.trustStore
使用
-Djavax.net.ssl.trustStore
未在JVM级别设置Truststore设置
The errors found (please include it in your question) are really related to the SSL connection 发现的错误(请将其包含在您的问题中)与SSL连接真正相关
package test;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
public class HTTPSCustomTruststore {
public final static void main (String argv[]) throws Exception{
request("https://www.google.com/", "test/google.jks", "pa55w0rd"); //Expected OK
request("https://www.aragon.es/","test/google.jks","pa55w0rd"); // Expected FAIL
request("https://www.aragon.es/",null,null); //using default truststore. OK
}
public static void configureCustom(HttpsURLConnection connection, String truststore, String pwd)throws Exception{
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keystore = KeyStore.getInstance("JKS");
InputStream keystoreStream = HTTPSCustomTruststore.class.getClassLoader().getResourceAsStream(truststore);
keystore.load(keystoreStream, pwd.toCharArray());
trustManagerFactory.init(keystore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustManagers, new java.security.SecureRandom());
SSLSocketFactory socketFact = context.getSocketFactory();
connection.setSSLSocketFactory(socketFact);
}
public static void request(String urlS, String truststore, String pwd) {
try {
URL url = new URL(urlS);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if (truststore != null) {
configureCustom((HttpsURLConnection) conn, truststore, pwd);
}
conn.connect();
int statusCode = conn.getResponseCode();
if (statusCode != 200) {
System.out.println(urlS + " FAIL");
} else {
System.out.println(urlS + " OK");
}
} catch (Exception e) {
System.out.println(urlS + " FAIL " + e.getMessage());
}
}
}
您可以将默认证书导入自定义商店以具有组合的自定义商店并使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.