用HttpClient连接访问SSL系统(以RTC为例)
最近测试通过HttpClient登录SSL连接的RTC,发现原先改了认证方式为HTTP BASE后的方式并不适用于SSL,由于SSL是在构建安全传输通道后进行传输,而通道构建需要验证key-store,之前在apache+php的网站上配置SSL是要有crt和key两个文件,现在所接触的RTC是Java开发的,使用Tomcat的时候在Tomcat的server.xml中配上keystore即可。
下面是最近收集的HttpClient访问SSL系统的资料,结合最近接触的RTC,整理后发出来为需要此方面资料的朋友做参考。所涉及开发工具及环境:IBM Rational Team Concert+Rational team concert 4.0.1
操作步骤:
一、生成KeyStore
这一步是JDK自带的工具生成,保证配置好环境变量的同时,打开命令提示符,即运行中输入cmd。
输入如下命令:
keytool -genkey -alias tomcat -keyalg RSA -validity 60 -keystore E:\rtc.keystore
输出:
输入keystore密码:******
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: xxx
您的组织名称是什么?
[Unknown]: xxx
您所在的城市或区域名称是什么?
[Unknown]: xxx
您所在的州或省份名称是什么?
[Unknown]: xxx
该单位的两字母国家代码是什么
[Unknown]: xxx
CN=localhost, OU= xxx, O= xxx, L=xxx, ST=xxx, C=xxx 正确吗?
[否]: Y
输入的主密码(如果和 keystore 密码相同,按回车):*******
参数说明:
-genkey表示生成密钥
-validity指定证书有效期,这里是60天
-alias指定别名,这里是tomcat
-keyalg指定算法,这里是RSA
-keystore指定存储位置,这里是D:\rtc.keystore
使用的自定义密码为 123456
Keytool 详细命令说明请参考百度百科;
*其中 您的名字与姓氏是什么? localhost是网站的域名或者ip,根据实际情况填写。否者会出现证书上的名称无效。
二、配置tomcat服务器支持SSL
1、将生成的 rtc.keystore文件,放到tomcat根目录,替换根目录的ibm-team-ssl.keystore(这里特指RTC,自己开发的程序不会有这个文件,故可以随便放)。
修改tomcat根目录下的/conf/server.xml
<connector port="9443"
connectionTimeout="20000"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
clientAuth="false"
keystoreFile="ibm-team-ssl.keystore"
keystorePass="ibm-team"
protocol="HTTP/1.1"
SSLEnabled="true"
sslProtocol="${jazz.connector.sslProtocol}"
algorithm="${jazz.connector.algorithm}"
URIEncoding="UTF-8"
ciphers="SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"></connector>
将keystoreFile="ibm-team-ssl.keystore"值改为rtc.keystore,或者将keystore文件名改为ibm-team-ssl.keystore
然后将keystorePass="ibm-team"值改为123456,或者在生成keystore的时候设置密码为ibm-team。
可能有朋友问了,为什么不直接使用RTC本身的这个keystore呢?因为这个keystore经过笔者验证,是localhost的,一开始个人认为是安装配置的问题,后来多次安装验证发现不是,因为SSL证书是一对一的,为了自定义域名或者ip,便于后期使用,还是自己生成吧。
另外针对自己编写的程序如果加SSL,同样的方法。修改tomcat根目录下的/conf/server.xml,新增Connector(原注释里有):
<connector SSLEnabled="true"
URIEncoding="UTF-8"
clientAuth="false"
keystoreFile="conf/rtc.keystore"
keystorePass="123456"
maxThreads="150"
port="8443"
protocol="HTTP/1.1"
scheme="https"
secure="true"
sslProtocol="TLS"></connector>
这样你的tomcat就支持https访问了
属性说明:
port: 这个port属性(默认值是8443)是 TCP/IP端口数码,Tomcat在其上监听安全连接。你可以把它更改成任何你愿意要的数值(如默认的https通信,数目是443)。不过,在许多操作系统中,要想在比1024小的端口数码上运行Tomcat,需要特殊的设置。
redirectPort: 如果你在这里更改端口数值,你还必须更改在non-SSL连接器上的redirectPort 这个属性特定的值。这允许Tomcat自动地redirect那些试图访问有安全限制页面的用户,指明根据 Servlet 2.4 Specification要求,SSL是必需的
clientAuth: 如果你想要Tomcat要求所有的SSL客户在使用这个socket时出示用户认证书,把这个值设定为 true 。如果你想要Tomcat要求出示用户认证书,但是如果没有认证书也可以, 就把这个值设定为want 。
keystoreFile: 如果你产生的keystore文件不在Tomcat期望的默认地方(一个叫做.keystore 的文件在Tomcat运行的主目录),就添加这个属性。你可以指定一个绝对路径名称, 或者一个由$CATALINA_BASE环境变量而派生的相对路径名称。
keystorePass: 如果你使用一个不同的keystore(以及认证书)密码,而不是Tomcat期望的密码 (就是changeit),添加这个元素。
keystoreType: 如果使用一个PKCS12 keystore的话,就添加这个element。 有效的值是JKS 和 PKCS12
sslProtocol: 要在这个socket上被使用的加密/解密协定。如果你在使用Sun的JVM,我们不提倡更改 这个值。据报道,TLS协定的IBM's 1.4.1 实现与一些通用的浏览器不兼容。 如果是这样,就使用value SSL
ciphers: 这个socket允许使用的由逗号分隔开的加密密码列单。默认的情况下,任何可用的密码都允许被使用。
algorithm: 可用的X509算法。默认是Sun的实现( SunX509 )。 对于IBM JVMs,你应该使用值 IbmX509。对于其他卖主,查阅JVM文档资料来 找正确的值。
truststoreFile: 用来验证用户认证书的TrustStore文件。
truststorePass: 访问TrustStore的密码。默认值就是keystorePass的值。
truststoreType: 如果你在使用与KeyStore不同格式的TrustStore,添加这个元素。 合法的值是JKS和PKCS12
keyAlias: 如果 keystore 里面有多个 key,你可以为用这个选项为加入的 key 起一个名字。 如果没有指定名字,使用时 keystore 内的第一个 key 将会被使用
三、用浏览器访问你的应用
输入:https://localhost:9443/ccm/web,能够访问说明你的应用已经处于SLL安全通道中了。
四、用httpClient访问https
利用官方的一个例子来说明:
public class ClientCustomSSL {
public final static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File("d:\\rtc.keystore"));
try {
//加载keyStore d:\\rtc.keystore
trustStore.load(instream, "123456".toCharArray());
} finally {
try { instream.close(); } catch (Exception ignore) {}
}
//穿件Socket工厂,将trustStore注入
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
//创建Scheme
Scheme sch = new Scheme("https", 9443, socketFactory);
//注册Scheme
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
//创建http请求(get方式)
HttpGet httpget = new HttpGet("https://localhost:9443/ccm/rootservices");
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
String ss = EntityUtils.toString(entity);
EntityUtils.consume(entity);
}
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
运行程序:
executing requestGET https://localhost:9443/ccm/rootservices HTTP/1.1
----------------------------------------
HTTP/1.1 200 OK
状态码200,说明已经成功访问到RTC了,访问到了,但只能通过OSLC查看rootservices,要进行进一步的操作,还需要认证,具体细节尚在学习中,有待总结后发出来分享。
