android 让webview支持https 双向认证(SSL)

来源:互联网 发布:朋友陪你醉网络歌手 编辑:程序博客网 时间:2024/05/22 06:22

前言:

参考了org.sandrob.sslexample和http://blog.csdn.net/mingli198611/article/details/9233705的实现方式,结合实际情况才完成该技术难题,现在分享一下我的实现方案来弥补这方面的空白。


正文:

1.android 4.0(不包含)以下版本的实现方法:

1.1 书写认证

[java] view plain copy
  1. private SSLContext createSSLContext() {  
  2.         SSLContext localSSLContext = null;  
  3.     try {  
  4.         // 创建一个证书库,并将证书导入证书库  
  5.         KeyStore keyStore = KeyStore.getInstance("PKCS12""BC");  
  6.         keyStore.load(  
  7.                 mContext.getResources().openRawResource(R.raw.client),//client 是*.pfx文件  
  8.                 CERTFILE_PASSWORD.toCharArray());//CERTFILE_PASSWORD 为你的证书的密码  
  9.         KeyManagerFactory localKeyManagerFactory = KeyManagerFactory  
  10.                 .getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  11.         localKeyManagerFactory.init(keyStore,  
  12.                 CERTFILE_PASSWORD.toCharArray());  
  13.         KeyManager[] arrayOfKeyManager = localKeyManagerFactory  
  14.                 .getKeyManagers();  
  15.         localSSLContext = SSLContext.getInstance("TLS");  
  16.         localSSLContext.init(arrayOfKeyManager, trustAllCerts,  
  17.                 new SecureRandom());              
  18.         } catch (Exception ex) {  
  19.             ex.printStackTrace();  
  20.         }  
  21.         return localSSLContext;  
  22.     }  


[java] view plain copy
  1. /** 
  2.      * 设置webview的ssl双向认证 
  3.      * 注意:改方法只支持android4.0(不包含)一下 
  4.      * 该方法调用一次即可 
  5.      * <P>Author : mingli </P>   
  6.      * <P>Date : 2013-7-2 </P> 
  7.      */  
  8.     public boolean setWebViewSSLCert() {  
  9.         boolean issuc = false;// true 代表验证和设置成功  
  10.         if (Build.VERSION.SDK_INT >= 14){  
  11.             return issuc;  
  12.         }  
  13.           
  14.         try {             
  15.             Field[] arrayOfField = Class.forName(  
  16.                     "android.net.http.HttpsConnection").getDeclaredFields();  
  17.             for (Field localField : arrayOfField) {  
  18.                 if (localField.getName().equals("mSslSocketFactory")) {//采用反射的方式修改mSslSocketFactory变量  
  19.                     localField.setAccessible(true);  
  20.                     localField.set(null,createSSLContext().getSocketFactory());  
  21.                     issuc = true;  
  22.                     break;  
  23.                 }  
  24.             }  
  25.         } catch (Exception ex) {  
  26.             ex.printStackTrace();  
  27.         }  
  28.         return issuc;  
  29.     }  


1.2 调用

        在webview初始化或者application 等,需要用https认证的地方调用 setWebViewSSLCert方法即可。

2.android 4.0(包含)以上版本的实现方法:

2.1 书写认证

[java] view plain copy
  1. private X509Certificate[] mX509Certificates;  
  2. private PrivateKey mPrivateKey;   
  3. private void initPrivateKeyAndX509Certificate()  
  4.     throws Exception {  
  5.         KeyStore keyStore;  
  6.  // 创建一个证书库,并将证书导入证书库  
  7. KeyStore keyStore = KeyStore.getInstance("PKCS12""BC");  
  8. keyStore.load(  
  9. mContext.getResources().openRawResource(R.raw.client),  
  10. CERTFILE_PASSWORD.toCharArray());  
  11.     Enumeration<?> localEnumeration;  
  12.     localEnumeration = keyStore.aliases();  
  13.     while (localEnumeration.hasMoreElements()) {  
  14.             String str3 = (String) localEnumeration.nextElement();  
  15.             mPrivateKey = (PrivateKey) keyStore.getKey(str3,  
  16.                     CERTFILE_PASSWORD.toCharArray());  
  17.             if (mPrivateKey == null) {  
  18.                 continue;  
  19.             } else {  
  20.                 Certificate[] arrayOfCertificate = keyStore  
  21.                         .getCertificateChain(str3);  
  22.                 mX509Certificates = new X509Certificate[arrayOfCertificate.length];  
  23.                 for (int j = 0; j < mX509Certificates.length; j++) {  
  24.                     mX509Certificates[j] = ((X509Certificate) arrayOfCertificate[j]);  
  25.                 }  
  26.             }  
  27.         }  
  28.     }  
  29.   
  30.   
  31. public class BasicWebViewClientEx extends WebViewClient {     
  32.   
  33.   
  34.     private X509Certificate[] certificatesChain;  
  35.     private PrivateKey clientCertPrivateKey;  
  36.         
  37.     public BasicWebViewClientEx(AbstractActivity activity) {  
  38.         mActivity = activity;  
  39.         certificatesChain = getX509Certificates();//此处就是上文中的mX509Certificates  
  40.         clientCertPrivateKey = getPrivateKey();//次处就是上文中的mPrivateKey  
  41.     }  
  42.       
  43.     public void onReceivedClientCertRequest(WebView view,  
  44.             ClientCertRequestHandler handler, String host_and_port) {  
  45.                 //注意该方法是调用的隐藏函数接口。这儿是整个验证的技术难点:就是如何调用隐藏类的接口。  
  46.                 //方法:去下载一个android4.2版本全编译后的class.jar 然后导入到工程中  
  47.         if((null != clientCertPrivateKey) && ((null!=certificatesChain) && (certificatesChain.length !=0))){  
  48.             handler.proceed(this.clientCertPrivateKey, this.certificatesChain);   
  49.         }else{  
  50.             handler.cancel();  
  51.         }         
  52.     }  
  53.   
  54.   
  55.           
  56.     @Override  
  57.     public void onReceivedSslError(final WebView view, SslErrorHandler handler,  
  58.             SslError error) {         
  59.         handler.proceed();    
  60.     }  
  61.       
  62. }  

2.2 调用

mWebView.setWebViewClient(new BasicWebViewClientEx());

2.3 编译

方案一:到android 4.2 源码环境下编译
方案二:(推荐)


1.去下载一个全编译的class.jar(http://download.csdn.net/detail/sfhong2008/5506219)
2.把该class.jar导入工程。步骤如下:(http://www.linuxidc.com/Linux/2012-02/54978.htm)
使用Eclipse,Android工程添加library(BuildPath -> Add Libraries->User Library->New User Library),将.jar文件加入添加到library,同时勾选“SystemLibrary”选项,www.linuxidc.com 以避免产生“java.lang.OutOfMemoryError:Java Heap Space”错误。如果已经正确导入了jar库,却仍然找不到隐藏的API。原因可能是Buildclass path order不正确,即android.jar和classes.jar的导入顺序不对,具体调节Buildclass path order,选择Build Path-> Config Build Path->Order and Export,调整自定义的library与android.jar的顺序。
3.编译
0 0
原创粉丝点击