频道栏目
首页 > 资讯 > 其他 > 正文

关于使用HttpClient访问https安全链接,双向认证核心部分实例讲解

18-07-30        来源:[db:作者]  
收藏   我要投稿

在开文之前,首先了解几个问题

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司(Netscape)进行,并内置于其浏览器Netscape Navigator中,提供了身份验证与加密通讯方法。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。[1]

什么是HTTPS?

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。

为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密

HTTPS和HTTP的区别?

HTTPS和HTTP的区别主要为以下四点:

一、https协议需要到ca申请证书,一般免费证书很少,需要交费。

二、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。

三、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

四、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

带着这些问题去实现,详细了解可以https://baike.baidu.com/item/https/285356fr=aladdin从此链接了解。

代码部分

现在第三方的网络框架也是比较多的,万变不离其中,其核心部分都是采用httpUrlConnection和httpClient所以其中用那个访问都会配置一个SSLSocketFactory的父类,也就是和SSL协议相关。

SSLSocketFactory实现部分

package com.nuctech.handheldlock.https;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
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.ssl.SSLSocketFactory;

public class HttpClientSSLSocketFactory extends SSLSocketFactory {

	SSLContext sslContext = SSLContext.getInstance("TLS");

	public HttpClientSSLSocketFactory(KeyStore truststore)

	throws NoSuchAlgorithmException, KeyManagementException,

	KeyStoreException, UnrecoverableKeyException {

		super(truststore);

		TrustManager tm = new X509TrustManager() {

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// TODO Auto-generated method stub

			}

			@Override
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// TODO Auto-generated method stub

			}
		};
		sslContext.init(null, new TrustManager[] { tm }, null);
	}

	@Override
	public Socket createSocket(Socket socket, String host, int port,
			boolean autoClose) throws IOException, UnknownHostException {
		return sslContext.getSocketFactory().createSocket(socket, host, port,
				autoClose);
	}

	@Override
	public Socket createSocket() throws IOException {
		return sslContext.getSocketFactory().createSocket();
	}
}

单项认证,可以跳过证书部分

代码如下


public static HttpClient getNewHttpClient() {
	 try {
	  KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
	  trustStore.load(null, null);
	  
	  SSLSocketFactory sf = new HttpClientSSLSocketFactory(trustStore);
	  sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
	  
	  HttpParams params = new BasicHttpParams();
	  HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
	  HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
	  
	  SchemeRegistry registry = new SchemeRegistry();
	  //registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
	  registry.register(new Scheme("https", sf, 8443));
	  
	  ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
	  
	  return new DefaultHttpClient(ccm, params);
	 } catch (Exception e) {
	  return new DefaultHttpClient();
	 }
	 }
双项认证,客户端和服务端都需要验证证书。

代码部分


private static final String KEY_STORE_TYPE_BKS = "bks";

	private static final String KEY_STORE_TYPE_P12 = "PKCS12";

	private static final String SCHEME_HTTPS = "https";

	private static final int HTTPS_PORT = 8444;

	private static final String KEY_STORE_CLIENT_PATH = "iekey.p12";

	private static final String KEY_STORE_TRUST_PATH = "client.truststore";

	private static final String KEY_STORE_PASSWORD = "changeit";

	private static final String KEY_STORE_TRUST_PASSWORD = "changeit";

	private static KeyStore keyStore;

	private static KeyStore trustStore;

	public static HttpClient getSslHttpClient(Context pContext) {

		HttpClient httpsClient = new DefaultHttpClient();

		try {

			// 服务器端需要验证的客户端证书

			keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);

			// 客户端信任的服务器端证书

			trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS);

			InputStream ksIn = pContext.getResources().getAssets()
					.open(KEY_STORE_CLIENT_PATH);

			InputStream tsIn = pContext.getResources().getAssets()
					.open(KEY_STORE_TRUST_PATH);

			try {

				keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());

				trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());

			} catch (Exception e) {

				e.printStackTrace();

			} finally {

				try {

					ksIn.close();

				} catch (Exception ignore) {

				}

				try {

					tsIn.close();

				} catch (Exception ignore) {

				}

			}

			SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore,
					KEY_STORE_PASSWORD, trustStore);
			socketFactory.setHostnameVerifier(new X509HostnameVerifier() {
				
				@Override
				public void verify(String arg0, String[] arg1, String[] arg2)
						throws SSLException {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public void verify(String arg0, X509Certificate arg1) throws SSLException {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public void verify(String arg0, SSLSocket arg1) throws IOException {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public boolean verify(String arg0, SSLSession arg1) {
					// TODO Auto-generated method stub
					return true;
				}
			});
			Scheme sch = new Scheme(SCHEME_HTTPS, socketFactory , HTTPS_PORT);

			httpsClient.getConnectionManager().getSchemeRegistry()
					.register(sch);

		} catch (KeyManagementException e) {

			e.printStackTrace();

		} catch (UnrecoverableKeyException e) {

			e.printStackTrace();

		} catch (KeyStoreException e) {

			e.printStackTrace();

		} catch (FileNotFoundException e) {

			e.printStackTrace();

		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();

		} catch (ClientProtocolException e) {

			e.printStackTrace();

		} catch (IOException e) {

			e.printStackTrace();

		}

		return httpsClient;

	}

代码看起来比较多,但是只需要一个辅助类即可搞定

相关TAG标签
上一篇:Android开发之引用外部数据库操作讲解
下一篇:CoordinatorLayout的简单使用介绍
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站