Android HttpsURLConnection SSL验证


本文只针对Android端使用HttpsURLConnection进行SSL验证的情况,HttpClient及其它第三方成熟的网络请求框架的配置不在此介绍,https介绍及证书相关知识建议使用前详细查阅。

1、cer,crt证书使用

Google官方有示例(https://developer.android.com/training/articles/security-ssl.html

将证书文件xx.cer或xx.crt 放到项目工程如raw、assets目录下,为了使用方便一般都放到raw目录下

核心代码:

 

CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = context.getResources().openRawResource(R.raw.xx); Certificate ca; try { ca = cf.generateCertificate(caInput); } finally { caInput.close(); } String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); urlConnection = (HttpsURLConnection) url.openConnection(); ((HttpsURLConnection) urlConnection).setSSLSocketFactory(context.getSocketFactory()); ((HttpsURLConnection) urlConnection).setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });

 

2、bks格式证书使用

同样将证书文件xx.bks 放到项目工程raw目录下

核心代码:

 

KeyStore ks = KeyStore.getInstance("BKS"); InputStream stream = context.getResources().openRawResource(R.raw.xx); ks.load(stream, null); stream.close(); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(ks); SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustManagerFactory.getTrustManagers(), null); urlConnection = (HttpsURLConnection) url.openConnection(); ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sc.getSocketFactory());
((HttpsURLConnection) urlConnection).setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });

 

但是,大部分情况下得到的可能是 JKS 格式或者是 CRT CER文件,如果要转成BKS使用,下面介绍方法。

http://bouncycastle.org/latest_releases.html下载支持BKS格式转换的jar包,使用keytool工具转换,命令如下:

keytool -importcert -v -trustcacerts -file "path_to_cert/xx.cer" -alias xx -keystore "path_to_your/xx.bks"

-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar"

-storetype BKS -storepass password

 

另外GUI工具KeyStore Explorer也支持转换

使用异常

java.io.IOException: Hostname 'xx.com' was not verified

可能是服务器配置不全有识或者用虚拟主机导致,实际上正式使用时一般会加上一个customHostnameVerifier,加上下划线代码可解决,但比较暴力。

 

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x63e562b0: Failure in SSL library, usually a protocol error

此异常发生笔者碰到过两种情况,一种原因是服务端HTTPS配置不支持SSLv3,在Android sdk4.4以下版本里建立安全连接时协议版本从TLSv1回落到SSLv3,解决方法

另外一种比较诡异,在没有给urlConnection对象调用setHostnameVerifier方法时也抛出了此异常,设置hostnameVerifier后正常。

 

有误请指正,转载请标明出处。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM