远程服务采用了双向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");

解决方案 »

  1.   

    使用 KeyStoreManager 和 TrustManager 就可以了,参考代码: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();
        }
    }import javax.net.ssl.KeyManager;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;public class MySSLContext {    private String protocol;
        private MyKeyManager keyManager;
        private MyTrustManager trustManager;    public MySSLContext(String protocol, MyKeyManager keyManager, MyTrustManager trustManager) {
            this.protocol = protocol;
            this.keyManager = keyManager;
            this.trustManager = trustManager;
        }    public MySSLContext(String protocol, MyTrustManager trustManager) {
            this(protocol, null, trustManager);
        }    public MySSLContext(String protocol, MyKeyManager keyManager) {
            this(protocol, keyManager, null);
        }    public SSLContext getSSLContext() {
            try {
                SSLContext context = SSLContext.getInstance(protocol);
                context.init(getKeyManagers(), getTrustManagers(), null);
                return context;
            } catch (Exception e) {
                throw new IllegalStateException("error, protocol: " + protocol, e);
            }
        }    private KeyManager[] getKeyManagers() {
            if (keyManager == null) {
                return null;
            }
            return keyManager.getKeyManagers();
        }    private TrustManager[] getTrustManagers() {
            if (trustManager == null) {
                return null;
            }
            return trustManager.getTrustManagers();
        }
    }import java.security.KeyStore;import javax.net.ssl.KeyManager;
    import javax.net.ssl.KeyManagerFactory;public class MyKeyManager {    private KeyStore ks;
        private char[] password;    public MyKeyManager(String keyStore, char[] password) {
            this(KeyStoreType.JKS, keyStore, password);
        }    public MyKeyManager(KeyStoreType type, String keyStore, char[] password) {
            this.password = password;
            this.ks = MyKeyStoreUtil.loadKeyStore(type, keyStore, password);
        }    public KeyManager[] getKeyManagers() {
            try {
                KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(ks, password);
                return kmf.getKeyManagers();
            } catch (Exception e) {
                throw new KeyStoreRuntimeException("cannot get KeyManagers", e);
            }
        }
    }import java.security.KeyStore;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;public class MyTrustManager {    private KeyStore ks;    public MyTrustManager(String keyStore, char[] password) {
            this(KeyStoreType.JKS, keyStore, password);
        }    public MyTrustManager(KeyStoreType type, String keyStore, char[] password) {
            this.ks = MyKeyStoreUtil.loadKeyStore(type, keyStore, password);
        }    public TrustManager[] getTrustManagers() {
            return new TrustManager[]{ new ClientTrustManager() };
        }    private class ClientTrustManager implements X509TrustManager {
            private X509TrustManager sunJSSEX509TrustManager;        public ClientTrustManager() {
                loadTrust();
            }        private void loadTrust() {
                try {
                    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    tmf.init(ks);
                    TrustManager tms[] = tmf.getTrustManagers();
                    for (int i = 0; i < tms.length; i++) {
                        if (tms[i] instanceof X509TrustManager) {
                            sunJSSEX509TrustManager = (X509TrustManager) tms[i];
                            return;
                        }
                    }
                } catch (Exception e) {
                    throw new KeyStoreRuntimeException(e);
                }
            }        @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
            }        @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
            }        @Override
            public X509Certificate[] getAcceptedIssuers() {
                return sunJSSEX509TrustManager.getAcceptedIssuers();
            }
        }
    }import java.io.FileInputStream;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.KeyStoreException;public class MyKeyStoreUtil {    private MyKeyStoreUtil() {
        }    public static KeyStore loadKeyStore(KeyStoreType type, String keyStore, char[] password) {
            if (type == null) {
                type = KeyStoreType.JKS;
            }
            InputStream in = null;
            try {
                try {
                    KeyStore ks = type.getKeyStore();
                    in = new FileInputStream(keyStore);
                    ks.load(in, password);
                    return ks;
                } finally {
                    if (in != null) {
                        in.close();
                    }
                }
            } catch (Exception e) {
                throw new KeyStoreRuntimeException("type: " + type +
                        ", keyStore: " + keyStore, e);
            }
        }    public static enum KeyStoreType {
            JKS {
                @Override
                public KeyStore getKeyStore() throws KeyStoreException {
                    return getKeyStore("JKS");
                }
            },        PKCS12 {
                @Override
                public KeyStore getKeyStore() throws KeyStoreException {
                    return getKeyStore("PKCS12");
                }
            };        public abstract KeyStore getKeyStore() throws KeyStoreException ;        private static KeyStore getKeyStore(String type) throws KeyStoreException {
                return KeyStore.getInstance(type);
            }
        }    public static class KeyStoreRuntimeException extends RuntimeException {        private static final long serialVersionUID = 1L;        public KeyStoreRuntimeException(String message, Throwable cause) {
                super(message, cause);
            }        public KeyStoreRuntimeException(Throwable cause) {
                super(cause);
            }
        }
    }
      

  2.   

    实际上就是通过 KeyStoreManager, TrustManager 创建 SSLContext 对象,再通过 SSLContext 对象创建 SSLSocketFactory 对象,并将 SSLSocketFactory 对象赋给 HttpsURLConnection 对象。KeyStoreManager 管理着双向认证中的客户端证书库
    TrustManager 管理着双向认证中服务端证书信任库,相当于浏览器中我知道该证书非 CA 签发,但我需要继续操作。
      

  3.   

    我采用的是xfire来连接ssl 加密的webservice, 楼上有例子么?