HttpClient HTTPS使用方法

处理HTTPS协议

HttpClient提供了对SSL的支持,在使用SSL之前必须安装JSSE。在Sun提供的1.4以后的版本中,JSSE已经集成到JDK中,如果你使用的是JDK1.4以前的版本则必须安装JSSE。JSSE不同的厂家有不同的实现。下面介绍怎么使用HttpClient来打开Https连接。这里有两种方法可以打开https连接,第一种就是得到服务器颁发的证书,然后导入到本地的keystore中;另外一种办法就是通过扩展HttpClient的类来实现自动接受证书。

方法1,取得证书,并导入本地的keystore:

•安装JSSE(如果你使用的JDK版本是1.4或者1.4以上就可以跳过这一步)。本文以IBM的JSSE为例子说明。先到IBM网站上下载JSSE的安装包。然后解压开之后将ibmjsse.jar包拷贝到\lib\ext\目录下。

•取得并且导入证书。证书可以通过IE来获得:

1. 用IE打开需要连接的https网址,会弹出如下对话框:
2. 单击"View Certificate",在弹出的对话框中选择"Details",然后再单击"Copy to File",根据提供的向导生成待访问网页的证书文件
3. 向导第一步,欢迎界面,直接单击"Next",
4. 向导第二步,选择导出的文件格式,默认,单击"Next",
5. 向导第三步,输入导出的文件名,输入后,单击"Next",
6. 向导第四步,单击"Finish",完成向导
7. 最后弹出一个对话框,显示导出成功

•用keytool工具把刚才导出的证书倒入本地keystore。Keytool命令在\bin\下,打开命令行窗口,并到\lib\security\目录下,运行下面的命令:
keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer

其中参数alias后跟的值是当前证书在keystore中的唯一标识符,但是大小写不区分;参数file后跟的是刚才通过IE导出的证书所在的路径和文件名;如果你想删除刚才导入到keystore的证书,可以用命令:
keytool -delete -keystore cacerts -storepass changeit -alias yourEntry1

•写程序访问https地址。如果想测试是否能连上https,只需要稍改一下GetSample例子,把请求的目标变成一个https地址。
GetMethod getMethod = new GetMethod("https://www.yourdomain.com");

运行该程序可能出现的问题:

1.抛出异常java.net.SocketException: Algorithm SSL not available。出现这个异常可能是因为没有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入这样的一行:
if(Security.getProvider("com.ibm.jsse.IBMJSSEProvider") == null)
Security.addProvider(new IBMJSSEProvider());

或者也可以打开\lib\security\java.security,在行
security.provider.1=sun.security.provider.Sun
security.provider.2=com.ibm.crypto.provider.IBMJCE

后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider

2.抛出异常java.net.SocketException: SSL implementation not available。出现这个异常可能是你没有把ibmjsse.jar拷贝到\lib\ext\目录下。

3.抛出异常javax.net.ssl.SSLHandshakeException: unknown certificate。出现这个异常表明你的JSSE应该已经安装正确,但是可能因为你没有把证书导入到当前运行JRE的keystore中,请按照前面介绍的步骤来导入你的证书。

方法2,扩展HttpClient类实现自动接受证书

因为这种方法自动接收所有证书,因此存在一定的安全问题,所以在使用这种方法前请仔细考虑您的系统的安全需求。具体的步骤如下:

•提供一个自定义的socket factory(test.MySecureProtocolSocketFactory)。这个自定义的类必须实现接口org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory,在实现接口的类中调用自定义的X509TrustManager(test.MyX509TrustManager),这两个类可以在随本文带的附件中得到
•创建一个org.apache.commons.httpclient.protocol.Protocol的实例,指定协议名称和默认的端口号
Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);

•注册刚才创建的https协议对象
Protocol.registerProtocol("https ", myhttps);

•然后按照普通编程方式打开https的目标地址,代码请参见test.NoCertificationHttpsGetSample
处理代理服务器

HttpClient中使用代理服务器非常简单,调用HttpClient中setProxy方法就可以,方法的第一个参数是代理服务器地址,第二个参数是端口号。另外HttpClient也支持SOCKS代理。

httpClient.getHostConfiguration().setProxy(hostName,port);


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。