Android在使用HttpClient访问https时认证策略

Android中自带Apache的HttpClient包,详见google的API[url]
http://developer.android.com/reference/org/apache/http/package-summary.html
[/url]所以在无需要任何引用的情况下就可以使用HttpClient相关的东西。但是,Android中的HttpClient与 http://hc.apache.org/downloads.cgi中的httpclient还是有所区别的,最主要的一个区别就是,Post方法时,Android的包支持自动重定向,而Apache官方的包不支持。
当访问https时,认证方案在客户端可以决定是否验证服务器,而服务器端可以选择是否验证客户端,如果双方都选择验证那么,就是双向验证;如果有一方选择不验证,那就是单向验证。作为客户端的Android单向验证和双向验证如下。
1 单向验证,即不验证服务器,在连接过程中首先读取本地客户端证书,然后采用不验证服务端信任证书的方式建立SSLContext,建立主要过程如下:
Java代码 复制代码 收藏代码
  1. protected Object doInBackground(Object... params) { 
  2.             // TODO Auto-generated method stub 
  3.              
  4.             try
  5.                 KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KEY_MANAGER); 
  6.                 KeyStore keyKeyStore = KeyStore.getInstance(KEY_KEYSTORE); 
  7.                  
  8.                 File fk=new File(mKPath); 
  9.                 FileInputStream kIs = new FileInputStream(fk); 
  10.                  
  11.                 keyKeyStore.load(kIs,KSPWD.toCharArray()); 
  12.                 kIs.close();  
  13.                 keyManager.init(keyKeyStore,KSPWD.toCharArray()); 
  14.                 GetSecPolicy client=new GetSecPolicy(HOST, SERVER_PORT, keyManager.getKeyManagers()); 
  15.                 UserID=client.getUserID(targetPage, null, null, true); 
  16.                 toast.setText(UserID); 
  17.                 toast.show(); 
  18.                  
  19.                  
  20.                  
  21.                 if("1".equals(UserID)){ 
  22.                     System.out.println("用户名或密码错误!UserID:"+UserID);                   
  23.                     toast.setText("用户名或密码错误!"); 
  24.                     toast.show(); 
  25.                 }else
  26.                     System.out.println("用户名和密码认证成功!UserID:"+ UserID); 
  27.                     //toast.setText("用户名和密码认证成功!"); 
  28.                     //toast.show(); 
  29.                                              
  30.                     //取出IMEI值,进行终端检查 
  31.                     TelephonyManager tm = (TelephonyManager) SoftCertUserLogin.this.getSystemService(Context.TELEPHONY_SERVICE); 
  32.                     String deviceId = tm.getDeviceId();//取出IMEI                                      
  33.                     //进行终端检查 
  34.                     System.out.println(OpenVpnAnimationActivity.USER_TYPE); 
  35.                     boolean check = client.secCheck(UserID, OpenVpnAnimationActivity.USER_TYPE, deviceId); 
  36.                      
  37.                     System.out.println(OpenVpnAnimationActivity.USER_TYPE); 
  38.  
  39.                      
  40.                     if(check){//验证通过 
  41.                     //获取用户的的用户信息策略 
  42.                         System.out.println("checked!"); 
  43.  
  44.                          
  45.                         String loginPolicy = client.getSecLoginPolicy(UserID); 
  46.                          
  47.                         if(loginPolicy == null){ 
  48.                             toast.setText("获取用户信息策略失败!"); 
  49.                             toast.show(); 
  50.                             System.out.println("获取用户信息策略失败!"); 
  51.                         }else{//成功获取seclogininfo 
  52.                             System.out.println(loginPolicy); 
  53.                             Intent intent = new Intent(); 
  54. //                          intent.putExtra("loginPolicy", loginPolicy);//传给下一个Activity 
  55.                             intent.setClass(SoftCertUserLogin.this, MainpageActivity.class); 
  56.                              
  57.                             Bundle mBundle = new Bundle(); 
  58.                             mBundle.putString("Seclogin", loginPolicy);//压入数据 
  59.                             intent.putExtras(mBundle);  
  60.                              
  61.                             SoftCertUserLogin.this.startActivity(intent); 
  62.                              
  63.                             if(version  >= 5) {       
  64.                                 overridePendingTransition(R.anim.zoomin, R.anim.zoomout);  //此为自定义的动画效果,下面两个为系统的动画效果    
  65.                                 //overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);      
  66.                                 //overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);    
  67.                             } 
  68.                              
  69.                              
  70.                             SoftCertUserLogin.this.finish(); 
  71.  
  72.                         } 
  73.                     }else{//验证失败 
  74.                         toast.setText("并没有绑定此手机,请重新登录!"); 
  75.                         toast.show(); 
  76.                         System.out.println("并没有绑定此手机,请重新登录!"); 
  77.                     } 
  78.                  
  79.                 } 
  80.  
  81.  
  82.             }catch(Exception e){ 
  83.                 toast.setText("错误:"+e.getMessage()); 
  84.                 toast.show(); 
  85.             } 
  86.              
  87.             return null
  88.         } 
protected Object doInBackground(Object... params) {
			// TODO Auto-generated method stub
			
			try{
	    		KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KEY_MANAGER);
				KeyStore keyKeyStore = KeyStore.getInstance(KEY_KEYSTORE);
				
				File fk=new File(mKPath);
				FileInputStream kIs = new FileInputStream(fk);
				
				keyKeyStore.load(kIs,KSPWD.toCharArray());
				kIs.close(); 
				keyManager.init(keyKeyStore,KSPWD.toCharArray());
				GetSecPolicy client=new GetSecPolicy(HOST, SERVER_PORT, keyManager.getKeyManagers());
				UserID=client.getUserID(targetPage, null, null, true);
		    	toast.setText(UserID);
		    	toast.show();
		    	
		    	
		    	
		    	if("1".equals(UserID)){
		    		System.out.println("用户名或密码错误!UserID:"+UserID);   				
		    		toast.setText("用户名或密码错误!");
		    		toast.show();
		    	}else{
		    		System.out.println("用户名和密码认证成功!UserID:"+ UserID);
		    		//toast.setText("用户名和密码认证成功!");
		    		//toast.show();
		    								
		    		//取出IMEI值,进行终端检查
		    		TelephonyManager tm = (TelephonyManager) SoftCertUserLogin.this.getSystemService(Context.TELEPHONY_SERVICE);
		    		String deviceId = tm.getDeviceId();//取出IMEI	    		        				
		    		//进行终端检查
		    		System.out.println(OpenVpnAnimationActivity.USER_TYPE);
		    		boolean check = client.secCheck(UserID, OpenVpnAnimationActivity.USER_TYPE, deviceId);
		    		
		    		System.out.println(OpenVpnAnimationActivity.USER_TYPE);

		    		
		    		if(check){//验证通过
		    		//获取用户的的用户信息策略
			    		System.out.println("checked!");

		    			
		    			String loginPolicy = client.getSecLoginPolicy(UserID);
		    			
		    		    if(loginPolicy == null){
		    		    	toast.setText("获取用户信息策略失败!");
		    		    	toast.show();
			    			System.out.println("获取用户信息策略失败!");
		    		    }else{//成功获取seclogininfo
		    		    	System.out.println(loginPolicy);
		    		    	Intent intent = new Intent();
//		    		    	intent.putExtra("loginPolicy", loginPolicy);//传给下一个Activity
		    		    	intent.setClass(SoftCertUserLogin.this, MainpageActivity.class);
		    		    	
		    		    	Bundle mBundle = new Bundle();
		    		    	mBundle.putString("Seclogin", loginPolicy);//压入数据
		    		    	intent.putExtras(mBundle); 
		    		    	
		    		    	SoftCertUserLogin.this.startActivity(intent);
		    		    	
		    				if(version  >= 5) {      
		    					overridePendingTransition(R.anim.zoomin, R.anim.zoomout);  //此为自定义的动画效果,下面两个为系统的动画效果   
		    					//overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);     
		    					//overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);   
		    				}
		    				
		    		    	
		    		    	SoftCertUserLogin.this.finish();

		    		    }
		    		}else{//验证失败
		    			toast.setText("并没有绑定此手机,请重新登录!");
		    			toast.show();
		    			System.out.println("并没有绑定此手机,请重新登录!");
		    		}
		    	
		    	}


	    	}catch(Exception e){
	        	toast.setText("错误:"+e.getMessage());
	        	toast.show();
	    	}
			
			return null;
		}

其中MySSLSocketFactory实现如下:
Java代码 复制代码 收藏代码
  1. import java.io.IOException; 
  2. import java.net.Socket; 
  3. import java.net.UnknownHostException; 
  4. import java.security.KeyManagementException; 
  5. import java.security.KeyStore; 
  6. import java.security.KeyStoreException; 
  7. import java.security.NoSuchAlgorithmException; 
  8. import java.security.UnrecoverableKeyException; 
  9. import java.security.cert.CertificateException; 
  10. import java.security.cert.X509Certificate; 
  11.  
  12. import javax.net.ssl.KeyManager; 
  13. import javax.net.ssl.SSLContext; 
  14. import javax.net.ssl.TrustManager; 
  15. import javax.net.ssl.X509TrustManager; 
  16.  
  17.  
  18.  
  19. import org.apache.http.conn.ssl.SSLSocketFactory; 
  20.  
  21. public class MySSLSocketFactory extends SSLSocketFactory { 
  22.         SSLContext sslContext = SSLContext.getInstance("TLS"); 
  23.  
  24.         public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
  25.             super(truststore); 
  26.  
  27.             TrustManager tm = new X509TrustManager() { 
  28.                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  29.                 } 
  30.  
  31.                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  32.                 } 
  33.  
  34.                 public X509Certificate[] getAcceptedIssuers() { 
  35.                     return null
  36.                 } 
  37.             }; 
  38.  
  39.             sslContext.init(null, new TrustManager[] { tm }, null); 
  40.         } 
  41.          
  42.         public MySSLSocketFactory(KeyManager[] keys,KeyStore truststore ) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
  43.             super(truststore); 
  44.  
  45.             TrustManager tm = new X509TrustManager() { 
  46.                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  47.                 } 
  48.  
  49.                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  50.                 } 
  51.  
  52.                 public X509Certificate[] getAcceptedIssuers() { 
  53.                     return null
  54.                 } 
  55.             }; 
  56.  
  57.             sslContext.init(keys, new TrustManager[] { tm }, null); 
  58.         } 
  59.  
  60.         @Override 
  61.         public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { 
  62.             return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 
  63.         } 
  64.  
  65.         @Override 
  66.         public Socket createSocket() throws IOException { 
  67.             return sslContext.getSocketFactory().createSocket(); 
  68.         } 
  69.     } 
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.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;



import org.apache.http.conn.ssl.SSLSocketFactory;

public class MySSLSocketFactory extends SSLSocketFactory {
        SSLContext sslContext = SSLContext.getInstance("TLS");

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

            TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

            sslContext.init(null, new TrustManager[] { tm }, null);
        }
        
        public MySSLSocketFactory(KeyManager[] keys,KeyStore truststore ) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);

            TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

            sslContext.init(keys, 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();
        }
    }

2 双向认证,即读取服务器端的信任证书
建立httpclient的SSLContext如下:
Java代码 复制代码 收藏代码
  1. SSLContext sslContext = SSLContext.getInstance(Constants.SSL.AGREEMENT);    
  2.                     KeyManagerFactory keyManager = KeyManagerFactory.getInstance(Constants.SSL.KEY_MANAGER);    
  3.                     TrustManagerFactory trustManager = TrustManagerFactory.getInstance(Constants.SSL.TRUST_MANAGER);    
  4.                      
  5.                     KeyStore keyKeyStore = KeyStore.getInstance(Constants.SSL.KEY_KEYSTORE);    
  6.                     KeyStore trustKeyStore = KeyStore.getInstance(Constants.SSL.TRUST_KEYSTORE);    
  7.                      
  8.                     FileInputStream kIs = new FileInputStream(mPath); 
  9.                     keyKeyStore.load(kIs,KSPWD.toCharArray()); 
  10.                     kIs.close();    
  11.                      
  12.                     FileInputStream tkIS = new FileInputStream(mPath); 
  13.                     trustKeyStore.load(tkIS,TKSPWD.toCharArray()); 
  14.                     tkIS.close(); 
  15.                      
  16.                     keyManager.init(keyKeyStore,KSPWD.toCharArray());    
  17.                     trustManager.init(trustKeyStore); 
  18.                      
  19.                     sslContext.init(keyManager.getKeyManagers(), trustManager.getTrustManagers(), null);    
  20.                      
SSLContext sslContext = SSLContext.getInstance(Constants.SSL.AGREEMENT);   
		            KeyManagerFactory keyManager = KeyManagerFactory.getInstance(Constants.SSL.KEY_MANAGER);   
		            TrustManagerFactory trustManager = TrustManagerFactory.getInstance(Constants.SSL.TRUST_MANAGER);   
		            
		            KeyStore keyKeyStore = KeyStore.getInstance(Constants.SSL.KEY_KEYSTORE);   
		            KeyStore trustKeyStore = KeyStore.getInstance(Constants.SSL.TRUST_KEYSTORE);   
		            
		            FileInputStream kIs = new FileInputStream(mPath);
		            keyKeyStore.load(kIs,KSPWD.toCharArray());
		            kIs.close();   
		            
		            FileInputStream tkIS = new FileInputStream(mPath);
		            trustKeyStore.load(tkIS,TKSPWD.toCharArray());
		            tkIS.close();
		            
		            keyManager.init(keyKeyStore,KSPWD.toCharArray());   
		            trustManager.init(trustKeyStore);
		            
		            sslContext.init(keyManager.getKeyManagers(), trustManager.getTrustManagers(), null);   
		            

在MySSLSocketFactory中添加相应构造函数即可。

  • [同时需要指明,android只支持bks格式的密库,而且android中自带 BouncyCastle的包,不同版本 BouncyCastle生成的密库是不兼容的,所以要注意密库版本]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值