在一个应用中,如何针对不同的外部客户系统,使用不同的数字证书?

来源:互联网 发布:2017网络十大英语热词 编辑:程序博客网 时间:2024/05/22 03:16

问题:

在项目中要向不同的外部应用通过https连接访问webservice,
但是Java中用System.setProperty("javax.net.ssl.keyStore",...), 多个证书无法同时设置,会有冲突,请问这个该怎么处理


解决:

使用 KeyStoreManager 和 TrustManager 就可以了

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


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);        }    }}


0 0
原创粉丝点击