Android笔记之证书

           android主要的通信方式是http和https,但是为了加强安全性,比较建议采用https。

      目前HttpClient建议不要再使用了,因为在高版本的android系统中逐渐废弃这种apache的api,转而采用原生的HttpURLConnection方式

      那么如何保证https通信安全呢,默认方式下https是信任所有证书的,因此容易受到中间人攻击,所以需要添加证书校验这一环节,下面主要介绍添加证书的两种方式:

     1、自定义证书

           这种方式允许开发人员用自签的证书来进行https通信,首先是要继承SSLSocketFactory

public class MySSLSocketFactory extends SSLSocketFactory {


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


    public UnifiedSSLSocketFactory(KeyStore truststore)
            throws NoSuchAlgorithmException, KeyManagementException,
            KeyStoreException, UnrecoverableKeyException {
        super(truststore);
        MyTrustManager tm = new MyTrustManager(truststore);
        context.init(null, new TrustManager[]{tm}, new SecureRandom());
    }


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


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


}



然后实现X509TrustManager:

public class MyTrustManager implements X509TrustManager {
   
    private X509TrustManager localTrustManager;
    public UnifiedTrustManager(KeyStore localKeyStore) throws KeyStoreException {
        try {          
            this.localTrustManager = createTrustManager(localKeyStore);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    private X509TrustManager createTrustManager(KeyStore store) throws NoSuchAlgorithmException, KeyStoreException {
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init((KeyStore) store);
        TrustManager[] trustManagers = tmf.getTrustManagers();
        return (X509TrustManager) trustManagers[0];
    }
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {        
            localTrustManager.checkServerTrusted(chain, authType);
        
    }
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
    public X509Certificate[] getAcceptedIssuers() {      
        X509Certificate[] result = localTrustManager.getAcceptedIssuers();            
        return result;
    }
}


其中关于keystore的获取方式是将自签的证书放进自定目录下,然后进行下面的处理:

  
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
   trustStore.load(null, null); 
    ...
   FileInputStream in = new FileInputStream(file);//这里的file就是你的自签证书
   CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    trustStore.setCertificateEntry("ca", certificateFactory.generateCertificate(in)); 

    
经过上面的步骤就能创建你自定义的SSLSocketFactory ,最后一个步骤就是使用这个SSLSocketFactory 了,如下:
HttpsURLConnection con = (HttpURLConnection) requestURL.openConneciton();
con.setSSLSocketFactory(mySSLSocketFactory);




2、上传证书到系统

      有时候连接只信任系统证书,比如用WebView的时候,因此这时候你需要把你的证书上传到系统目录下才有效果,具体方法如下:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
				Intent intent = KeyChain.createInstallIntent();
				Certificate cert = SSLUtil.getCert(context);
				if(null != cert) {					
					try {
						intent.putExtra(KeyChain.EXTRA_CERTIFICATE,cert.getEncoded());
						intent.putExtra(KeyChain.EXTRA_NAME, "ca");
						startActivityForResult(intent, REQUEST_CODE_INSTALL_CERT_TO_SYS);
					} catch (CertificateEncodingException e) {
						e.printStackTrace();
					}
				}
} 



if里面的判断是因为在API低于4.0的android系统是不支持将自定义证书上传到系统目录下的,调用这个方法系统会弹出一个对话框让用户选择是否安装指定证书,用户同意后才能将证书放到系统目录,另外并没有api可以删除系统证书,只能用户手动到设置里面删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值