Android 使用httpclient对self-signed certificate网站进行SSL连线

<!--[if gte mso 9]><![endif]-->

AndroidSDK在进行https连线时,对于自签署的凭证是会拒绝连线的,会得到Nottrustedservercertificate的例外。如果使用HttpsURLConnection来连线,网络上可以找到一些破解方法,在此不多谈。使用apachehttpclient其实执行效率比较差一点,但是他最大的好处就是有内建的机制储存cookie,并且也可以跟随server作自动转址。网络上资料比较多的是httpclient3.x版,Android使用httpclient4(而且还有些实作被拿掉)唯一找到比较可信的来源是apachehttpclient官方的example。节录重点段落如下:

        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream instream = new FileInputStream(new File("my.keystore"));
        try {
            trustStore.load(instream, "nopassword".toCharArray());
        } finally {
            instream.close();
        }

        SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
        Scheme sch = new Scheme("https", socketFactory, 443);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);
直接把这段拿去用当然只有一个死字。本来看讨论以为是要制造一个假的空凭证骗过httpclient,从Android档案系统有点微妙开始改来改去,一连串不同的例外或直接crash就不多谈了。解决了档案路径,到底有没有建立等等方面的问题之后才终于发现,假凭证是不行的

1.所以首先,开启你PCMac上的浏览器连上目标网站,从凭证管理的地方把该网站的凭证汇出。每个浏览器做法都不同,请各位发挥正常工程师的水准做完这件事。以Firefox为例,找到site名后选汇出,多半是会得到一个档名为your_site_name.crtX509(PEM)凭证档。为了之后使用方便,先把这档案复制一份并把档名改为your_site_name.pem

2.将这个凭证格式从PEM转为BKS格式。这是关键性的一步啊。


KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());

这行中的getDefaultType到底会get到什么type呢?答案:在Android中是BKS。有J2ME经验的人会想说,我看多半是跟J2ME一样的SunJKS格式吧,而且,我不要用getDefaultType就好了,我可以自己指定为PEM,JKS格式啊。是的,你可以。只是你会得到错误讯息说KeyStoreJKSimplementationnotfound。测了半天,看起来Androidhttpclient只吃BKS就对了,其他都没实作。

3.那格式要怎么转?根据网路上找到的资料,可以使用KeyToolIUI这个Java工具。打开后从介面选create→ KeyStore,格式选BKS,自己命名一下,要不要设密码都可。接着选import→Keystore’sentry→Trustedcertificate→RegularcertificateSource的部分选PEM并选到刚刚浏览器得到的那个档,Target当然选BKS和刚create出来的档。按OK之后会跳出Entries视窗,下方提示你enternewalias,随便取个名字后ok连打,顺利的话你应该就会有一个your_keystore.bks之类的档案了。


4.要把凭证档放在Androidapp能读到的地方,做法有两种,放在SDcard中,或直接放在resources中。


[方案一]放在SDcard的情形:首先模拟器要挂上SDcard,这在EclipseAVD工具产生avd时就可以顺便指定SD了。如果习惯用指令的话,也可以用如下指令产生imagemount上:

$mksdcard512Mmy_sdcard.so

$emulator-sdcard./my_sdcard.so

再来要把凭证档copySDcard中,目前只知道指令的做法:

$adbpushfile_path/your_keystore.bks/sdcard

如果有显示类似ftp传输速度之类的讯息应该就是成功了。

接着把android程式码中档案部分改一改

FileInputStream instream = new FileInputStream(new File("/sdcard/your_keystore.bks"));

trustStore.load(instream, null);

如果没设密码,可以把keystoreload的第二个密码参数改成null,有设的话当然就改成你的密码。

基本上这样应该就大功告成了


[方案二]再讲讲凭证放在resources的方法。

首先把档案复制到专案下的res/raw/your_keystore.bks

Eclipse没有错误的话就ok,否则多半是你档名不合规格,稍微改改。接着取用方法是把android程式码改成:

InputStream instream = getResources().openRawResource(R.raw.your_keystore);

其它同SDcard


5.还有一个地方要注意,就是SSLport

Schemesch=newScheme("https",socketFactory,443);

如果你要连的网站不是用port443,这边请记得改掉。


6.另外如果要使用档案放在resources的做法,getResources()应该只能在Activityclass中执行,如果另外包装连线类别的话请不要直接服用上面的程式码,要自行从context抓到资源再传过去。


原文地址:http://blog.aztaru.com/2009/12/11/%E8%9D%91%E7%97%AA%EF%BF%BD%EF%BF%BD-android-%E9%9B%BF%E8%BC%BB%E6%AC%9Fhttpclient%E6%92%A0%E8%A7%82elf-signed-certificate%E8%9D%AC%E8%84%A9%EF%BF%BD%E2%92%A4%EF%BF%BD%E8%84%B0%EF%BF%BD%E6%91%84sl%EF%BF%BD%EF%BF%BD%EF%A1%8E%EF%BF%BD%EF%BF%BD/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值