读书人

java client访问https server(客户端

发布时间: 2012-12-24 10:43:14 作者: rapoo

java client访问https server(客户端代码、服务器端配置)
openssl配置证书时直接配置crt、key即可
而jsse通过keystore来存储证书、证书链信息,java客户端通过jsse来使用ssl
具体openssl和keytool各种证书类型之间的转换可以参考“收藏”中一些文章

cfca颁发的pfx个人证书需要转换成keystore格式才能使用
从cfca获得如下测试证书:
个人证书:cfca_client.pfx
服务器证书:cfca_server.crt、cfca_server.key
根证书:CFCA_RCA.cer(一级根证书)、cfca_root.crt(二级根证书)

以下以上述cfca的证书为例,其实也可以自己用openssl生成自己的ca自己的服务器、客户端证书进行测试
服务器证书和个人证书都从同一个ca签发,生成keystore时只需要分别把根证书、服务器证书生成服务器端的keystore文件;根证书、客户端个人证书生成客户端的keystore文件,即可完成证书配置,而不需要将服务器端证书加入客户端的keystore文件,也不需要将客户端证书加入服务器端的keystore文件,他们之间通过相同的根证书来建立互相信任,这样客户端、服务器端的keyStore和trustStore都分别指向一个jks文件即可
但是,如果客户端、服务器端根证书不一致,就需要在客户端新建一个可信任的keystore文件信任服务器端的根证书,在服务器端另建一个可信任的keystore文件信任客户端的根证书,配置时分别陪在trustStore中,而自己的证书作为keyStrore配置

一、服务器端配置
1、如果通过apache做负载均衡,只需要配置在apache上即可
apache ssl的配置参考文章《rhel5+apache+jboss+ssl》
将上述证书文件复制到服务器目录下,修改$APACHE_HOME/conf/extra/httpd-ssl.conf


tcServerKeystore.jks文件时根据上述cfca证书生成的,具体参考后面内容

2.2 tomcat也支持APR connector,按照openssl的方式直接配置证书(类似apache上的配置):

tomcat如何启用APR,参考tomcat文档:http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html

二、将pfx、crt、key等证书、密钥文件转换为keystore文件
需要用到openssl(linux下需要安装openssl包)
还要用到keytool(在$JAVA_HOME/jre/bin下)
1、客户端:将pfx证书转换为keystore
1.1 cfca的二级根证书文件时ascii格式的需要转换(可以用文本编辑器打开,是两段加密字符串):
用以下命令将ca根证书转换成DER格式



四、客户端代码troubleshooting
1、程序中如果keystore密码输错,将会出现异常
2、如果生成keystore时,keystore的保护密码和被导入的pfx的保护密码不一致将出现异常
3、如果服务器端的证书的cn与服务器的dns或者ip不一致,程序将报错:
URL url = new URL("https://xx.xxx.com:8443/docs");

而不能用ip地址替代xx.xxx.com,但是在第二段代码中ip和域名都可以,为什么会这样懒得深究了!
4、如果服务器的证书过期,可以修改客户端机器的时间

老革命碰到新问题,在另一台机器上测试出现以下异常(用第一段代码,使用jdk自带的HttpsURLConnection访问,用apache的httpclient没试过):
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:746)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:652)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1000)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
at com.stf.action.TestCert.main(TestCert.java:34)


在网上找了一下,原来是TLS的Renegotiation 的问题:
参考:http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html
http://httpd.apache.org/docs/trunk/mod/mod_ssl.html#sslinsecurerenegotiation

有两种解决方案(都测试通过)
1、修改apache的配置加上:SSLInsecureRenegotiation on
但这样似乎不安全:were vulnerable to a Man-in-the-Middle attack (CVE-2009-3555) during a renegotiation

2、将java端的jre升级,参考oralce的文档jdk1.6的话要升级到update22以上

1 楼 hwj_wj123 2012-03-15 你好,我看了您的这篇“java client访问https server(客户端代码、服务器端配置) ”,我现在也在实现java client访问https的功能,一直提示no_certification,困惑了好几天,还是不能解决,能指点一下吗。
我的处理步骤:
1.从网页上保存出证书,cer文件。
2.将导出的证书导入到jre/lib/security下的cacerts
3.
===========================简化后的相关代码==================
System.setProperty("javax.net.ssl.keyStore","d:\\...cacerts");
System.setProperty("javax.net.ssl.keyStorePassword","xxxxx");

HttpURLConnection connection = null;
InputStream in = null;
URL url = new URL(srcUrl);
connection = (HttpURLConnection) url.openConnection();
in = connection.getInputStream();
到这里就会出错,提示没有证书。这种方式可以实现getinputstream吗?
2 楼 linyfei 2012-05-07 您好,我想问下,上述文中提到:
有两种解决方案(都测试通过)
1、修改apache的配置加上:SSLInsecureRenegotiation on
但这样似乎不安全:were vulnerable to a Man-in-the-Middle attack (CVE-2009-3555) during a renegotiation

2、将java端的jre升级,参考oralce的文档jdk1.6的话要升级到update22以上

关于第一种,我想问下,修改apache的配置指的是修改apache的哪个配置文件?具体位置可以帮忙指明一下吗?谢谢!


读书人网 >编程

热点推荐