您的位置首页百科词条

如何使用ssl协议访问https网站?

如何使用ssl协议访问https网站?

项目里需要访问其他接口,通过http/https协议。我们一般是枣旦拦用HttpClient类来实现具体的http/https协议接口的调用。 // Init a HttpClient HttpClient client = new HttpClient(); String url=http://www.xxx.com/xxx; // Init a HttpMethod HttpMethod get = new GetMethod(url); get.setDoAuthentication(true); get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false)); // Call http interface try { client.executeMethod(get); // Handle the response from http interface InputStream in = get.getResponseBodyAsStream(); SAXReader reader = new SAXReader(); Document doc = reader.read(in); } finally { // Release the http connection get.releaseConnection(); } 以上代码在通过普通的http协议是没有问题的,但如果是https协议的话,就会有证书文件凳胡的要求了。一般情况下,是这样去做的。 // Init a HttpClient HttpClient client = new HttpClient(); String url=https://www.xxx.com/xxx; if (url.startsWith("https:")) { System.setProperty("javax.net.ssl.trustStore", "/.sis.cer"); System.setProperty("javax.net.ssl.trustStorePassword", "public"); } 于是,这里就需要事先生成一个.sis.cer的文件,生成这个文件的方法一般是先通过浏览器访问https://,导出证书文件,再用JAVA keytool command 生成证书 # $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer 但这样做,一比较麻烦,二来证书也有有效期,过了有效期之后,迟腔又需要重新生成一次证书。如果能够避开生成证书文件的方式来使用https的话,就比较好了。 还好,在最近的项目里,我们终于找到了方法。 // Init a HttpClient HttpClient client = new HttpClient(); String url=https://www.xxx.com/xxx; if (url.startsWith("https:")) { this.supportSSL(url, client); } 用到了supportSSL(url, client)这个方法,看看这个方法是如何实现的。 private void supportSSL(String url, HttpClient client) { if(StringUtils.isBlank(url)) { return; } String siteUrl = StringUtils.lowerCase(url); if (!(siteUrl.startsWith("https"))) { return; } try { setSSLProtocol(siteUrl, client); } catch (Exception e) { logger.error("setProtocol error ", e); } Security.setProperty( "ssl.SocketFactory.provider", "com.tool.util.DummySSLSocketFactory"); } private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception { URL url = new URL(strUrl); String host = url.getHost(); int port = url.getPort(); if (port <= 0) { port = 443; } ProtocolSocketFactory factory = new SSLSocketFactory(); Protocol authhttps = new Protocol("https", factory, port); Protocol.registerProtocol("https", authhttps); // set https protocol client.getHostConfiguration().setHost(host, port, authhttps); } 在supportSSL方法里,调用了Security.setProperty( "ssl.SocketFactory.provider", "com.tool.util.DummySSLSocketFactory"); 那么这个com.tool.util.DummySSLSocketFactory是这样的: 访问https 资源时,让httpclient接受所有ssl证书,在weblogic等容器中很有用 代码如下: 1. import java.io.IOException; 2. import java.net.InetAddress; 3. import java.net.InetSocketAddress; 4. import java.net.Socket; 5. import java.net.SocketAddress; 6. import java.net.UnknownHostException; 7. import java.security.KeyManagementException; 8. import java.security.NoSuchAlgorithmException; 9. import java.security.cert.CertificateException; 10. import java.security.cert.X509Certificate; 11. 12. import javax.net.SocketFactory; 13. import javax.net.ssl.SSLContext; 14. import javax.net.ssl.TrustManager; 15. import javax.net.ssl.X509TrustManager; 16. 17. import org.apache.commons.httpclient.ConnectTimeoutException; 18. import org.apache.commons.httpclient.params.HttpConnectionParams; 19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; 20. 21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { 22. static{ 23. System.out.println(">>>>in MySecureProtocolSocketFactory>>"); 24. } 25. private SSLContext sslcontext = null; 26. 27. private SSLContext createSSLContext() { 28. SSLContext sslcontext=null; 29. try { 30. sslcontext = SSLContext.getInstance("SSL"); 31. sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); 32. } catch (NoSuchAlgorithmException e) { 33. e.printStackTrace(); 34. } catch (KeyManagementException e) { 35. e.printStackTrace(); 36. } 37. return sslcontext; 38. } 39. 40. private SSLContext getSSLContext() { 41. if (this.sslcontext == null) { 42. this.sslcontext = createSSLContext(); 43. } 44. return this.sslcontext; 45. } 46. 47. public Socket createSocket(Socket socket, String host, int port, boolean autoClose) 48. throws IOException, UnknownHostException { 49. return getSSLContext().getSocketFactory().createSocket( 50. socket, 51. host, 52. port, 53. autoClose 54. ); 55. } 56. 57. public Socket createSocket(String host, int port) throws IOException, 58. UnknownHostException { 59. return getSSLContext().getSocketFactory().createSocket( 60. host, 61. port 62. ); 63. } 64. 65. 66. public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) 67. throws IOException, UnknownHostException { 68. return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); 69. } 70. 71. public Socket createSocket(String host, int port, InetAddress localAddress, 72. int localPort, HttpConnectionParams params) throws IOException, 73. UnknownHostException, ConnectTimeoutException { 74. if (params == null) { 75. throw new IllegalArgumentException("Parameters may not be null"); 76. } 77. int timeout = params.getConnectionTimeout(); 78. SocketFactory socketfactory = getSSLContext().getSocketFactory(); 79. if (timeout == 0) { 80. return socketfactory.createSocket(host, port, localAddress, localPort); 81. } else { 82. Socket socket = socketfactory.createSocket(); 83. SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); 84. SocketAddress remoteaddr = new InetSocketAddress(host, port); 85. socket.bind(localaddr); 86. socket.connect(remoteaddr, timeout); 87. return socket; 88. } 89. } 90. 91. //自定义私有类 92. private static class TrustAnyTrustManager implements X509TrustManager { 93. 94. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 95. } 96. 97. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 98. } 99. 100. public X509Certificate[] getAcceptedIssuers() { 101. return new X509Certificate[]{}; 102. } 103. } 104. 105. } public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { static{ System.out.println(">>>>in MySecureProtocolSocketFactory>>"); } private SSLContext sslcontext = null; private SSLContext createSSLContext() { SSLContext sslcontext=null; try { sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sslcontext; } private SSLContext getSSLContext() { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } return this.sslcontext; } public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket( socket, host, port, autoClose ); } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket( host, port 然后按如下方式使用HttpClient Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443); Protocol.registerProtocol("https", myhttps); HttpClient httpclient=new HttpClient();