android中的https使用自生成证书
说起https就得从android app加密说起。
想hack一个android应用,无非就是反编译和抓包两种办法。
反编译一般通过加壳和混淆来防止。
抓包么,就只能通过请求参数加密和https了。
重点说说https。
简单来说,https是通过ssl来进行数据加密的http。大致流程如下:
客户端和服务端使用非对称加密进行第一次握手,服务端保留私钥,把公钥发给客户端,客户端首先判断一下这个公钥是否有效,过期,颁发机构什么的。如果没问题,就先生成一个随机值,然后用这个公钥加密,发给服务端,此时只有持有私钥的服务端能解密,于是就得到了这个随机值。现在双方都有同样的随机值了,为后面进行的对称加密传输数据做准备,因为一直用公钥私钥这种非对称的加密太慢了。。。
具体到android 开发中如何实施呢:
1.首先我们要有个证书:
ps:网上铺天盖地那种信任所有证书的方式就不谈了,代码量太少,不专业。<(▰˘◡˘▰)>
keytool -genkey -alias icemantest -keystore fjajfd.keystore -validity 365
后面会让你输入名字,公司,地区,别名,密码,有效时间等等。
完成之后生成了名叫fjajfd.keystore的一个keystore。这个里面包含私钥。有的android签名用的证书是jks结尾的,也是使用jks证书库的,跟这个差不多。
2.从keystore里面导出证书,一般.cer这样的。里面包含公钥,这个是可以公开的,谁都可以用来加密,但是只有私钥才能解密。
keytool -export -alias icemantest -keystore fjajfd.keystore -file cer.cer
生成一个叫cer.cer的证书。
3.android 里面支持的证书是bks证书库格式的,而我们生成的是jks格式的,于是需要转换一下。
这里需要用到工具bc库bcprov-jdk15on-146.jar。
keytool -import -alias icemantest -file cer.cer -keystore bks.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /Users/iceman/Downloads/bcprov-jdk15on-146.jar
现在bks.bks这个文件就是包含了公钥的android上可以使用的证书了。
现在以我们应用里面使用的证书举例如何在代码中使用这个证书。
文件xxx.bks放在raw目录里面,方便直接读取。
android中一般使用httpurlconnection和httpclient访问网络,这两种情况下使用证书的方式稍有不同,但核心都在一个叫SSLSocketFactory的类上面。
先说httpurlconnection:
主机名验证:
这个可以使用默认的,看看这句明显是废话的代码就明白了:
1 | |
证书验证:
第一步:读取公钥信息到keystore中.
1 | |
第二步:使用这个keystore来初始化一个trustmanager, trustmanager简单来说,就是管理是否信任服务端的.
1 | |
第三步,使用得到的trustmanager来初始化一个SslContext,进而得到SocketFactory:
1 | |
得到SocketFactory之后就简单了,可以使用HttpsUrlconnetion的静态方法setDefaultSocketFactory来修改默认的,也可以在得到httpsurlconection以后调用setSSLSocketFactory方法来针对每个连接设置.
然后说说apache的httpclient中使用方法
读取公钥至keystore跟前者完全一样.
不同的是apache中也有个SocketFactory类,可以直接用keystore参数来构造,其主机名验证方式也有预设的3个级别:
1 | |
然后是分别绑定http和https至不同的端口并指定使用的socketfactory:
1 | |
得到上面这个SingleClientConnManager之后,可以继承DefaultHttpClient,重写createClientConnectionManager来返回这个SingleClientConnManager,也可以直接使用这个SingleClientConnManager来构建一个defaultHttpClient.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!