首先感谢http://www.infoq.com/cn/articles/keeping-your-secrets这篇文章解决了我的问题(即不能使用System.setProperty("https.protocols","TLSv1"); )
以下是两个https信任所有证书的实例:
package com.colotnet.util;import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;public class HttpUtil {public static String send(String url, List<BasicNameValuePair> nvps, String ecoding) throws Exception{String respStr = null;DefaultHttpClient httpClient = new SSLClient();HttpPost postMethod = new HttpPost(url);postMethod.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));try{HttpResponse resp = httpClient.execute(postMethod);int statusCode = resp.getStatusLine().getStatusCode();if(statusCode == HttpStatus.SC_OK){respStr = EntityUtils.toString(resp.getEntity(), "UTF-8");}}catch(Exception e){ throw e;}finally{postMethod.releaseConnection();}return respStr;}public static InputStream post(String submitUrl, String reqData, int connectTimeOut, int readTimeOut, String encoding) throws Exception {
// String path = "E:/Bill99QuickPay/81231015722198890.jks";
// File certFile = new File(path);
// KeyStore ks = KeyStore.getInstance("JKS");
// String password = "vpos123";
// ks.load(new FileInputStream(certFile), password.toCharArray());
// KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
// kmf.init(ks, password.toCharArray());TrustManager[] tm = { new MyX509TrustManager() };
// SSLContext sslContext = SSLContext.getInstance("TLSv1");
// System.setProperty("https.protocols","TLSv1"); String protocol = sslContext.getProtocol();System.out.println(protocol);
// sslContext.init(kmf.getKeyManagers(),tm, null);sslContext.init(null, tm, new java.security.SecureRandom());SSLSocketFactory factory = sslContext.getSocketFactory();SSLSocketFactoryWrapper wrapper = new SSLSocketFactoryWrapper(factory, new String[] { "TLSv1" }, null);URL url = new URL(submitUrl);HttpsURLConnection urlc = (HttpsURLConnection) url.openConnection();urlc.setSSLSocketFactory(wrapper);urlc.setHostnameVerifier(new TrustAnyHostnameVerifier());urlc.setDoOutput(true); urlc.setDoInput(true); urlc.setReadTimeout(readTimeOut);urlc.setConnectTimeout(connectTimeOut);OutputStream out = urlc.getOutputStream();out.write(reqData.getBytes(encoding));out.flush(); out.close();return urlc.getInputStream();
}// public static String send(String url, String param,int readTimeout, int connTimeOut, String readecoding,String txtType, String sendecoding) throws Exception{
// String respStr = null;
// HttpClient httpClient = new HttpClient();
// PostMethod postmethod = new PostMethod(url);
// // 链接超时
// httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connTimeOut);
// // 读取超时
// httpClient.getHttpConnectionManager().getParams().setSoTimeout(readTimeout);
// try{
// postmethod.setRequestEntity(new StringRequestEntity(param, txtType,sendecoding));
// int statusCode = httpClient.executeMethod(postmethod);
// if (statusCode == HttpStatus.SC_OK) {
// BufferedInputStream bis = new BufferedInputStream(postmethod.getResponseBodyAsStream());
// byte[] bytes = new byte[1024];
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
// int count = 0;
// while ((count = bis.read(bytes)) != -1) {
// bos.write(bytes, 0, count);
// }
// byte[] strByte = bos.toByteArray();
// respStr = new String(strByte, 0, strByte.length, readecoding);
// }
// }catch(Exception e){
// throw e;
// }finally{
// postmethod.releaseConnection();
// }
// return respStr;
// }}
package com.colotnet.util;import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;public class SSLClient extends DefaultHttpClient {public SSLClient() throws Exception {super();SSLContext ctx = SSLContext.getInstance("TLSv1");X509TrustManager tm = new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}};ctx.init(null, new TrustManager[] { tm }, null);SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);ClientConnectionManager ccm = this.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();sr.register(new Scheme("https", 443, ssf));}
}
package com.colotnet.util;import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class MyX509TrustManager implements X509TrustManager { public MyX509TrustManager() throws Exception { } /* * Delegate to the default trust manager. */ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } /* * Delegate to the default trust manager. */ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } /* * Merely pass this through. */ public X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[0]; }
}
package com.colotnet.util;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;public class TrustAnyHostnameVerifier implements HostnameVerifier {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}}
package com.colotnet.util;import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;public class SSLSocketFactoryWrapper extends SSLSocketFactory {private final SSLSocketFactory wrappedFactory;private final String[] enabledProtocols;private final String[] enabledSuites;public SSLSocketFactoryWrapper(SSLSocketFactory factory, String[] protocols, String[] suites) {wrappedFactory = factory;enabledProtocols = protocols;enabledSuites = suites;}/*** @param host* @param port* @return* @throws IOException* @throws UnknownHostException* @see javax.net.SocketFactory#createSocket(java.lang.String, int)*/public Socket createSocket(String host, int port) throws IOException, UnknownHostException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket(host, port);setParameters(socket);return socket;}/*** @param host* @param port* @param localHost* @param localPort* @return* @throws IOException* @throws UnknownHostException* @see javax.net.SocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)*/public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException,UnknownHostException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket(host, port, localHost, localPort);setParameters(socket);return socket;}/*** @param host* @param port* @return* @throws IOException* @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int)*/public Socket createSocket(InetAddress host, int port) throws IOException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket(host, port);setParameters(socket);return socket;}/*** @param address* @param port* @param localAddress* @param localPort* @return* @throws IOException* @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int, java.net.InetAddress, int)*/public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket(address, port, localAddress, localPort);setParameters(socket);return socket;}/*** @return* @throws IOException* @see javax.net.SocketFactory#createSocket()*/public Socket createSocket() throws IOException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket();setParameters(socket);return socket;}/*** @return* @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()*/public String[] getDefaultCipherSuites() {return wrappedFactory.getDefaultCipherSuites();}/*** @return* @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()*/public String[] getSupportedCipherSuites() {return enabledSuites == null ? wrappedFactory.getSupportedCipherSuites() : enabledSuites;}/*** @param s* @param host* @param port* @param autoClose* @return* @throws IOException* @see javax.net.ssl.SSLSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)*/public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {SSLSocket socket = (SSLSocket)wrappedFactory.createSocket(s, host, port, autoClose);setParameters(socket);return socket;}/*** Override the configured parameters on the socket.** @param socket*/private void setParameters(SSLSocket socket) {if (enabledProtocols != null) {socket.setEnabledProtocols(enabledProtocols);}if (enabledSuites != null) {socket.setEnabledCipherSuites(enabledSuites);}}
}
注意的是SSLClient中信任所有证书的方式对jdk6不适用,HTTPUtil中的第二个方法可以用于jdk6,需指定System.setProperty("https.protocols","TLSv1"); 如果由于环境问题不能使用System,(System针对整个环境所有的https设置),可使用SSLSocketFactory的包装类 SSLSocketFactoryWrapper来指定一条http连接使用的协议。
本文链接:https://my.lmcjl.com/post/9126.html
展开阅读全文
4 评论