Android使用https链接

Https与Http类似,只不过Https一般是通过post请求服务器,但是Https与http不同的是Https与服务器会话是处于连接状态。http则发送请求后连接就会断开。

另外使用HttpsURLConnection时需要实现HostnameVerifier 和 X509TrustManager,这两个实现是必须的,要不会报安全验证异常。

package cn.yws.httpstest;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URL;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;

import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;



import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;



public class MainActivity extends Activity {
	
	private static final String tag = MainActivity.class.getSimpleName();
	private EditText editText1;
	private Handler handler=new Handler(new Handler.Callback() {
		
		@Override
		public boolean handleMessage(Message msg) {
			
			switch (msg.what) {
			case 10:
			{
				
				String html=(String) msg.obj;
				//子线程不能直接操作editText1
				editText1.setText(html);
			}
				break;

			default:
				break;
			}
			return false;
		}
	});
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		View button = this.findViewById(R.id.button);
		editText1=(EditText) findViewById(R.id.editText1);
	
		button.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				onclick();
			}});
	}
	//方法一使用HttpsURLConnection
	public void GetHttpsPost(String urlPath) throws Exception
	{		
		URL url = new URL(urlPath);	
		
		SSLContext sslctxt = SSLContext.getInstance("TLS");	
		sslctxt.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());	
		HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();	
		//多了两个
		conn.setSSLSocketFactory(sslctxt.getSocketFactory());
		conn.setHostnameVerifier(new MyHostnameVerifier());	
		
		conn.connect();	
		int respCode = conn.getResponseCode();
		Log.d(tag, "ResponseCode="+respCode);
		InputStream input = conn.getInputStream();		
		String result = toString(input);	
		//Log.d(tag, "result:"+result);
		
		Message msg=Message.obtain();
		msg.what=10;
		msg.obj=result;
		handler.sendMessage(msg);
		//子线程不能直接操作editText1
		//editText1.setText(result);
		input.close();		
		conn.disconnect();
	}
	private String toString(InputStream input){		
		String content = null;
		try{
		InputStreamReader ir = new InputStreamReader(input);
		BufferedReader br = new BufferedReader(ir);	
		StringBuilder sbuff = new StringBuilder();
		while(null != br){
			String temp = br.readLine();
			if(null == temp)break;
			sbuff.append(temp).append(System.getProperty("line.separator"));
		}		
		content = sbuff.toString();
		}catch(Exception e){
			e.printStackTrace();
		}		
		return content;
	}	
	
	public void runHttpsClient(View view)
	{
		String path="https://login.taobao.com/member/login.jhtml?spm=1.6659421.754894437.1.2pSgMy&f=top&redirectURL=http%3A%2F%2Fwww.taobao.com%2F";
		
		String html;
		try {
			html = sendHttpsClientPOSTRequest(path, null, "GBK");
			Message msg=Message.obtain();
			msg.what=10;
			msg.obj=html;
			handler.sendMessage(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	public static String sendHttpsClientPOSTRequest(String path, Map<String, String> params, String encoding) throws Exception{
		List<NameValuePair> pairs = new ArrayList<NameValuePair>();//存放请求参数
		if(params!=null && !params.isEmpty()){
			for(Map.Entry<String, String> entry : params.entrySet()){
				pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs, encoding);
		HttpPost httpPost = new HttpPost(path);   
		httpPost.setEntity(entity);
		HttpClient client = HttpClientHelper.getHttpClient();
		client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5*1000);
		HttpResponse response = client.execute(httpPost);
		if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            
        }
		return new String(readStream(response.getEntity().getContent()),encoding);
	}
	public static byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		return outSteam.toByteArray();
	}
	private void onclick(){
		
		new Thread(new Runnable(){

			@Override
			public void run() {
				try{
				String str = "https://www.oschina.net/home/login?goto_page=http%3A%2F%2Fwww.oschina.net%2F";
				//String str="https://login.taobao.com/member/login.jhtml?spm=1.6659421.754894437.1.2pSgMy&f=top&redirectURL=http%3A%2F%2Fwww.taobao.com%2F";
				GetHttpsPost(str);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			
		}).start();;
	}
	//要实现x209证书认证
	static class MyX509TrustManager implements X509TrustManager{

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			if(null != chain){
				for(int k=0; k < chain.length; k++){
					X509Certificate cer = chain[k];
					print(cer);
				}
			}
			Log.d(tag, "check client trusted. authType="+authType);
			
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			if(null != chain){
				for(int k=0; k < chain.length; k++){
					X509Certificate cer = chain[k];
					print(cer);
				}
			}
			Log.d(tag, "check  servlet trusted. authType="+authType);
			//是否信任服务器
			 Principal principal = null;
			 boolean isOK=false;
             for(X509Certificate x509Certificate : chain){
                     principal = x509Certificate.getSubjectDN();
                     Log.d(tag, "principal.getName():"+principal.getName());
                     if(principal != null &&(principal.getName().indexOf("www.oschina.net")!=-1)){
                    	 
                          isOK=true;
                          break;
                          //return ;
                     }                    
             }
             if(isOK==false){
            	 Log.d(tag, "访问非法域名");
            	 return ;
             }
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			
			Log.d(tag, "get acceptedissuer");
			
			return null;
		}
		
		
		private void print(X509Certificate cer){
			
			int version = cer.getVersion();
			String sinname = cer.getSigAlgName();
			String type = cer.getType();
			String algorname = cer.getPublicKey().getAlgorithm();
			BigInteger serialnum = cer.getSerialNumber();
			Principal principal = cer.getIssuerDN();
			String principalname = principal.getName();
			
			Log.d(tag, "version="+version+", sinname="+sinname+", type="+type+", algorname="+algorname+", serialnum="+serialnum+", principalname="+principalname);
		}
		
	}
	//要实现主机名验证
	static class MyHostnameVerifier implements HostnameVerifier{

		@Override
		public boolean verify(String hostname, SSLSession session) {
			
			Log.d(tag, "hostname="+hostname+",PeerHost= "+session.getPeerHost());
			return true;
		}
		
	}
	

}
package cn.yws.httpstest;
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 javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
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;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

//方法二、使用HttpClient
public class HttpClientHelper {

	private static HttpClient httpClient;

	private HttpClientHelper() {
		
	}

	public static synchronized HttpClient getHttpClient() {

		if (null == httpClient) {
			// 初始化工作
			try {
				KeyStore trustStore = KeyStore.getInstance(KeyStore
						.getDefaultType());
				trustStore.load(null, null);
				SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
				sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);  //允许所有主机的验证

				HttpParams params = new BasicHttpParams();

				HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
				HttpProtocolParams.setContentCharset(params,
						HTTP.DEFAULT_CONTENT_CHARSET);
				HttpProtocolParams.setUseExpectContinue(params, true);

				// 设置连接管理器的超时
				ConnManagerParams.setTimeout(params, 10000);
				// 设置连接超时
				HttpConnectionParams.setConnectionTimeout(params, 10000);
				// 设置socket超时
				HttpConnectionParams.setSoTimeout(params, 10000);

				// 设置http https支持
				SchemeRegistry schReg = new SchemeRegistry();
				schReg.register(new Scheme("http", PlainSocketFactory
						.getSocketFactory(), 80));
				schReg.register(new Scheme("https", sf, 443));

				ClientConnectionManager conManager = new ThreadSafeClientConnManager(
						params, schReg);

				httpClient = new DefaultHttpClient(conManager, params);
			} catch (Exception e) {
				e.printStackTrace();
				return new DefaultHttpClient();
			}
		}
		return httpClient;
	}

}

class SSLSocketFactoryEx extends SSLSocketFactory {

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

	public SSLSocketFactoryEx(KeyStore truststore)
			throws NoSuchAlgorithmException, KeyManagementException,
			KeyStoreException, UnrecoverableKeyException {
		super(truststore);

		TrustManager tm = new X509TrustManager() {

			@Override
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}

			@Override
			public void checkClientTrusted(
					java.security.cert.X509Certificate[] chain, String authType)
					throws java.security.cert.CertificateException {

			}

			@Override
			public void checkServerTrusted(
					java.security.cert.X509Certificate[] chain, String authType)
					throws java.security.cert.CertificateException {
				

			}
		};

		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();
	}
}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.yws.httpstest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="4" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="cn.yws.httpstest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="50dip"
            android:text="@string/hello_world" />

        <Button
            android:id="@+id/button2"
            android:layout_width="fill_parent"
            android:layout_height="50dip"
            android:onClick="runHttpsClient"
            android:text="@string/httpsclient" />
    </LinearLayout>

    <EditText
        android:id="@+id/editText1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignTop="@+id/ll"
        android:layout_marginTop="150dip"
        android:inputType="textMultiLine" >

        <requestFocus />
    </EditText>

</RelativeLayout>

另外附上tomcat配置https双向认证文档。

http://download.csdn.net/detail/earbao/7120093


  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值