gpt4 book ai didi

Java:通过资源加载 SSL keystore

转载 作者:搜寻专家 更新时间:2023-10-30 21:22:34 25 4
gpt4 key购买 nike

如果我有:

System.setProperty("javax.net.ssl.keyStore", '/etc/certificates/fdms/WS1001237590._.1.ks');
System.setProperty("javax.net.ssl.keyStorePassword", 'DV8u4xRVDq');
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");

我可以毫无问题地打开安全连接。

但是,我想将证书直接存储在 war 中,所以我使用:(文件输入流最终将成为资源流,但我这样做是为了让它工作。)

System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/etc/certificates/fdms/WS1001237590._.1.ks"), "DV8u4xRVDq".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "DV8u4xRVDq".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);

现在,如果我打开同一个连接,我会得到:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

最佳答案

前一段时间我不得不做类似的事情。我有一个证书文件,我必须想办法加载它并将其用于 SSL 连接。希望我所做的对您有所帮助。

首先我必须创建一个信任管理器:

public class MyX509TrustManager implements X509TrustManager {

X509TrustManager pkixTrustManager;

MyX509TrustManager() throws Exception {

String certFile = "/certificates/MyCertFile.cer";

Certificate myCert = CertificateFactory.getInstance("X509").generateCertificate(this.getClass().getResourceAsStream(valicertFile));

KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, "".toCharArray());
keyStore.setCertificateEntry("myCert", myCert);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init(keyStore);

TrustManager trustManagers[] = trustManagerFactory.getTrustManagers();

for(TrustManager trustManager : trustManagers) {
if(trustManager instanceof X509TrustManager) {
pkixTrustManager = (X509TrustManager) trustManager;
return;
}
}

throw new Exception("Couldn't initialize");
}

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
pkixTrustManager.checkServerTrusted(chain, authType);
}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
pkixTrustManager.checkServerTrusted(chain, authType);
}

public X509Certificate[] getAcceptedIssuers() {
return pkixTrustManager.getAcceptedIssuers();
}
}

之后我必须创建一个使用我的信任管理器的套接字工厂:

public class MySSLProtocolSocketFactory implements SecureProtocolSocketFactory {

private SSLContext sslContext = null;

public MySSLProtocolSocketFactory() {
super();
}

private static SSLContext createMySSLContext() {
try {
MyX509TrustManager myX509TrustManager = new MyX509TrustManager();
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new MyX509TrustManager[] { myX509TrustManager}, null);
return context;
}

catch(Exception e) {
Log.error(Log.Context.Net, e);
return null;
}
}

private SSLContext getSSLContext() {
if(this.sslContext == null) {
this.sslContext = createMySSLContext();
}

return this.sslContext;
}

public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
}

public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, final HttpConnectionParams params) throws IOException {
if(params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}

int timeout = params.getConnectionTimeout();
SocketFactory socketFactory = getSSLContext().getSocketFactory();

if(timeout == 0) {
return socketFactory.createSocket(host, port, localAddress, localPort);
}

else {
Socket socket = socketFactory.createSocket();
SocketAddress localAddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteAddr = new InetSocketAddress(host, port);
socket.bind(localAddr);
socket.connect(remoteAddr, timeout);
return socket;
}
}

public Socket createSocket(String host, int port) throws IOException {
return getSSLContext().getSocketFactory().createSocket(host, port);
}

public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}

public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(MySSLProtocolSocketFactory.class));
}

public int hashCode() {
return MySSLProtocolSocketFactory.class.hashCode();
}
}

然后我使用那个套接字工厂发送我的 POST:

Protocol.registerProtocol("myhttps", new Protocol("myhttps", new MySSLProtocolSocketFactory(), 443));

PostMethod postMethod = new PostMethod("myhttps://some.url.here");

HttpClient client = new HttpClient();
int status = client.executeMethod(postMethod);

我唯一想不通的是如何简单地将证书文件添加到常规 keystore 中。我在研究过程中发现的所有示例源代码都指向创建一个套接字因子,然后向该套接字工厂注册一个协议(protocol)。也许有一种方法可以简单地使用套接字工厂来建立连接而无需注册协议(protocol);我还没有彻底调查过。在我的特殊情况下,创建一个特定的协议(protocol)是必要的。希望这会让你走得更远。我承认这似乎有点迂回;我最初做的时候也有同样的感觉。但这是我让它工作的唯一方法。也许其他人有更好的解决方案。

关于Java:通过资源加载 SSL keystore ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3247746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com