在一个应用中,如何针对不同的外部客户系统,使用不同的数字证书?
2015-04-24 14:23
696 查看
问题:
在项目中要向不同的外部应用通过https连接访问webservice,
但是Java中用System.setProperty("javax.net.ssl.keyStore",...), 多个证书无法同时设置,会有冲突,请问这个该怎么处理
解决:
使用 KeyStoreManager 和 TrustManager 就可以了
实际上就是通过 KeyStoreManager, TrustManager 创建 SSLContext 对象,再通过 SSLContext 对象创建 SSLSocketFactory 对象,并将 SSLSocketFactory 对象赋给 HttpsURLConnection 对象。
KeyStoreManager 管理着双向认证中的客户端证书库
TrustManager 管理着双向认证中服务端证书信任库,相当于浏览器中我知道该证书非 CA 签发,但我需要继续操作。
在项目中要向不同的外部应用通过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); } } }
相关文章推荐
- 如何在一个系统下同时安装VS2010和VS2013并使用不同默认外部库
- 几台电脑同时使用一个无线路由器上网,外部ip相同,各个电脑内部ip不同,路由器如何区分某个数据包是发给某个电脑的?
- 如何在一个机器上针对不同的项目需求使用不同的pyhon版本和包
- [转]如何使用国际开源项目构建一个完整的GIS(地理信息)应用系统
- 如何使用国际开源项目构建一个完整的GIS(地理信息)应用系统
- 如何使用国际开源项目构建一个完整的GIS(地理信息)应用系统
- 如何使用国际开源项目构建一个完整的GIS(地理信息)应用系统
- Linux下如何颁发证书:学习使用openssl搭建一个CA
- 如何使用gcore工具获取一个core文件而不重启应用?
- windows 系统中打开一个数字证书所经历的过程
- 如何在 Windows Phone 应用程序的一个 Pivot 控件中使用不同的应用程序栏
- 使用iis设置虚拟主机(如何用同一端口ip对应不同web应用)
- 如何使用一个应用的插件包
- 如何在同一个页面内使用不同的超级链接,如何定义这类CSS。
- 一个使用敏捷开发平台构建的应用系统
- PKI基础 二.PKI基础--5.数字证书及应用(转,一个加密解密的全过程)
- 如何使用.Net来设计一个爬虫系统
- NS2学习笔记 在一个节点上同时使用不同的应用层协议
- 嵌入应用:如何制作和使用Jffs2文件系统 (zhuan)
- 如何使用Openfiler为VMware ESX设置一个免费的iSCSI或NAS储存系统