您的位置:首页 > 其它

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

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 签发,但我需要继续操作。

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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐