直接上实例:
我有一个私钥证书,访问我们公司内网:
a.pfx (PKCS12标准的证书)
需要用JAVA程序访问公司内网,内网采用SSL安全机制,并要求客户端出示身份证明,即a.pfx中的私钥。
需要做的事情:
1,把a.pfx导成根证书,放到trustkeyStore中去。以便在SSL握手中 客户端(我)信任 服务端(内网)用。
要做到a.pfx导出成 .cer后缀的证书文件很简单:
首先把a.pfx导入到IE。然后用IE的Internet选项--》内容--》证书--》导出成不带私钥的cer格式就搞定了
我按照以上步骤导出成a.pfx.cer 格式的证书
然后进行如下步骤:
# 用以下命令把cer格式的证书放到 server.keystore中去 keytool -import -v -trustcacerts -alias yajun.wuyj -file a.pfx.cer -storepass changeit -keystore server.keystore |
2,把私钥放到 keyStore中去,以便在SSL我手中,服务器要我出示我的身份证明时使用。
public class AuthSSLProtocolSocketFactory implements SecureProtocolSocketFactory {
private static final Log LOG = LogFactory.getLog(AuthSSLProtocolSocketFactory.class);
private String keystoreUrl = null;
private String keystorePassword = null;
private String truststoreUrl = null;
private String truststorePassword = null;
private SSLContext sslcontext = null;
public AuthSSLProtocolSocketFactory(final String keyStoreFile, String keystorePassword, String truststoreFile,
final String truststorePassword){
super();
this.keystoreUrl = keyStoreFile;
this.keystorePassword = keystorePassword;
this.truststoreUrl = truststoreFile;
this.truststorePassword = truststorePassword;
}
private static KeyStore createKeyStore(final String file, final String password) throws KeyStoreException,
NoSuchAlgorithmException,
CertificateException, IOException {
if (file == null) {
throw new IllegalArgumentException("Keystore url may not be null");
}
LOG.debug("Initializing key store");
KeyStore keystore = null;
InputStream is = null;
try {
// 尝试 使用PKCS12的格式读取私钥证书
keystore = KeyStore.getInstance("PKCS12");
is = new FileInputStream(new File(file));
keystore.load(is, password != null ? password.toCharArray() : null);
} catch (Exception ce) {
// 再次 尝试使用JKS的格式读取私钥证书
keystore = KeyStore.getInstance("jks");
is = new FileInputStream(new File(file));
keystore.load(is, password != null ? password.toCharArray() : null);
} finally {
IOUtils.closeQuietly(is);
}
return keystore;
}
private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password)
throws KeyStoreException,
NoSuchAlgorithmException,
UnrecoverableKeyException {
if (keystore == null) {
throw new IllegalArgumentException("Keystore may not be null");
}
LOG.debug("Initializing key manager");
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keystore, password != null ? password.toCharArray() : null);
return kmfactory.getKeyManagers();
}
private static TrustManager[] createTrustManagers(final KeyStore keystore) throws KeyStoreException,
NoSuchAlgorithmException {
if (keystore == null) {
throw new IllegalArgumentException("Keystore may not be null");
}
LOG.debug("Initializing trust manager");
TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init(keystore);
TrustManager[] trustmanagers = tmfactory.getTrustManagers();
for (int i = 0; i < trustmanagers.length; i++) {
if (trustmanagers[i] instanceof X509TrustManager) {
trustmanagers[i] = new AuthSSLX509TrustManager((X509TrustManager) trustmanagers[i]);
}
}
return trustmanagers;
}
private SSLContext createSSLContext() {
try {
KeyManager[] keymanagers = null;
TrustManager[] trustmanagers = null;
if (this.keystoreUrl != null) {
// 证明自己身份的keyStore
KeyStore keystore = createKeyStore(this.keystoreUrl, this.keystorePassword);
if (LOG.isDebugEnabled()) {
Enumeration<String> aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
Certificate[] certs = keystore.getCertificateChain(alias);
if (certs != null) {
LOG.debug("Certificate chain '" + alias + "':");
for (int c = 0; c < certs.length; c++) {
if (certs[c] instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) certs[c];
LOG.debug(" Certificate " + (c + 1) + ":");
LOG.debug(" Subject DN: " + cert.getSubjectDN());
LOG.debug(" Signature Algorithm: " + cert.getSigAlgName());
LOG.debug(" Valid from: " + cert.getNotBefore());
LOG.debug(" Valid until: " + cert.getNotAfter());
LOG.debug(" Issuer: " + cert.getIssuerDN());
}
}
}
}
}
keymanagers = createKeyManagers(keystore, this.keystorePassword);
}
if (this.truststoreUrl != null) {
// 信任其他的store
KeyStore keystore = createKeyStore(this.truststoreUrl, this.truststorePassword);
if (LOG.isDebugEnabled()) {
Enumeration<String> aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
LOG.debug("Trusted certificate '" + alias + "':");
Certificate trustedcert = keystore.getCertificate(alias);
if (trustedcert != null && trustedcert instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) trustedcert;
LOG.debug(" Subject DN: " + cert.getSubjectDN());
LOG.debug(" Signature Algorithm: " + cert.getSigAlgName());
LOG.debug(" Valid from: " + cert.getNotBefore());
LOG.debug(" Valid until: " + cert.getNotAfter());
LOG.debug(" Issuer: " + cert.getIssuerDN());
}
}
}
trustmanagers = createTrustManagers(keystore);
}
SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(keymanagers, trustmanagers, null);
return sslcontext;
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Unsupported algorithm exception: " + e.getMessage());
} catch (KeyStoreException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Keystore exception: " + e.getMessage());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("Key management exception: " + e.getMessage());
} catch (IOException e) {
LOG.error(e.getMessage(), e);
throw new AuthSSLInitializationError("I/O error reading keystore/truststore file: " + e.getMessage());
}
}
private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext();
}
return this.sslcontext;
}
public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort,
final HttpConnectionParams params) throws IOException, UnknownHostException,
ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
} else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
*/
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
*/
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port);
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
*/
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
3,SSL握手通过了,咱们就开始访问页面吧。
/**
* 访问内网的程序
*
* @author Administrator 2010-1-19 下午10:27:40
*/
public class pfxSSLExample {
private static final String KEYSTORE_FILE = "src/main/resources/a.pfx";
private static final String TRUST_KEY_FILE = "src/main/resources/server.keystore";
private static final String TRUST_PASSWORD = "changeit";
private static final String KEYSTORE_PASSWORD = "1983413";
public static void main(String[] args) throws Exception {
AuthSSLProtocolSocketFactory factory = new AuthSSLProtocolSocketFactory(KEYSTORE_FILE, KEYSTORE_PASSWORD,
TRUST_KEY_FILE, TRUST_PASSWORD);
Protocol.registerProtocol("https", new Protocol("https", factory, 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.cn.xxxx-inc.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getResponseBodyAsString());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpget.releaseConnection();
}
}
}