直接上实例:
我有一个私钥证书,访问我们公司内网:
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(); } } }