日期:2014-05-20  浏览次数:20749 次

java 连接两个 ssl远程服务的问题
远程服务采用了双向ssl认证,但是一下程序,只能设置一个jks文件的路径,如何同时可以连接两个远程服务?
System.setProperty("javax.net.ssl.keyStore", path);
System.setProperty("javax.net.ssl.keyStorePassword", "11111");
System.setProperty("javax.net.ssl.trustStore", path);
System.setProperty("javax.net.ssl.trustStorePassword", "11111");

------解决方案--------------------
使用 KeyStoreManager 和 TrustManager 就可以了,参考代码:

Java code
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

public class Test {

    public static void main(String[] args) throws Exception {

        // System.setProperty("javax.net.debug", "all");

        URL url = new URL("https://www.xxxx.com");

        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

        connection.setSSLSocketFactory(getSSLSocketFactory());

        InputStream in = connection.getInputStream();
        byte[] bys = new byte[8192];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int p = 0; (p = in.read(bys)) != -1;) {
            baos.write(bys, 0, p);
        }
        String str = new String(baos.toByteArray());
        System.out.println(str);
    }

    private static SSLSocketFactory getSSLSocketFactory() {
        MyKeyManager keyManager = new MyKeyManager(KeyStoreType.PKCS12, "d:/key.p12", "123456".toCharArray());
        MyTrustManager trustManager = new MyTrustManager("d:/trust.keystore", "123456".toCharArray());
        MySSLContext context = new MySSLContext("TLS", keyManager, trustManager);
        return context.getSSLContext().getSocketFactory();
    }
}

------解决方案--------------------
实际上就是通过 KeyStoreManager, TrustManager 创建 SSLContext 对象,再通过 SSLContext 对象创建 SSLSocketFactory 对象,并将 SSLSocketFactory 对象赋给 HttpsURLConnection 对象。

KeyStoreManager 管理着双向认证中的客户端证书库
TrustManager 管理着双向认证中服务端证书信任库,相当于浏览器中我知道该证书非 CA 签发,但我需要继续操作。