赞
踩
最近要做一个SSL的应用,用SSL进行双向身份验证意思就是在客户机连接服务器时,链接双方都要对彼此的数字证书进行验证,保证这是经过授权的才能够连接。我们链接一般的SSL时采用的是单向验证,客户机只验证服务器的证书,服务器不验证客户机的证书;而连接网上银行时使用的U盾就是用来存储进行双向验证所需要的客户端证书的。
Tomcat既可以作为独立的Servlet容器,也可以作为其他HTTP服务器附加的Servlet容器。如果Tomcat在非独立模式下工作,通常不必配置SSL,由它从属的HTTP服务器来实现和客户的SSL通信。Tomcat和HTTP服务器之间的通信无须采用加密机制,HTTP服务器将解密后的数据传给Tomcat,并把Tomcat发来的数据加密后传给客户。
如果Tomcat作为独立的Java Web服务器,则可以根据安全需要,为Tomcat配置SSL,它包含以下两个步骤:
(1) 准备安全证书。
(2) 配置Tomcat的SSL连接器(Connector)。
一、准备安全证书获得安全证书有两种方式:一种方式是到权威机构购买,还有一种方式是创建自我签名的证书。这里就介绍第二种获取证书的方式,毕竟免费的嘛!
SUN公司提供了制作证书的工具keytool。在JDK 1.4以后的版本中都包含了这一工具,它的位置为<JAVA_HOME>\bin\keytool.exe。
通过keytool工具创建证书的命令为:
keytool -genkeypair -alias "tomcat" -keyalg "RSA"以上命令将生产一对非对称密钥和自我签名的证书,这个命令中几个参数的意思如下:
-genkeypair:生成一对非对称密钥。-alias:指定密钥对的别名,该别名是公开的。-keyalg:指定加密算法,本例中的采用通用的RAS加密算法首先会提示输入keystore的密码。
然后提示输入个人信息,如姓名、组织单位和所在城市等,直接回车即可。
接着会提示输入信息是否正确,输入“y”表示信息正确。
最后要求输入<Tomcat>的主密码,这里设置与keystore相同的密码,因此只需根据提示按回车键即可。
二、配置SSL连接器在Tomcat的server.xml文件中,已经提供了现成的配置SSL连接器的代码,只要把<Connector>元素的注释去掉即可:
<!— Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the connector should be using the OpenSSL style configuration described in the APR documentation -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="C:\Documents and Settings\XuLiang\.keystore" keystorePass="SUNCHIS" ciphers="sunchis" />
实际上,基于SSL的HTTPS使用的默认端口是443。但Tomcat在这里将HTTPS端口设置为8443。<Connector>配置里的一些属性参数如下表:
clientAuth如果设为true(即双向认证)
keystoreFile指定keystore文件的存放位置
keystorePass指定keystore的密码
三、访问支持SSL的Web站点 |
由于SSL技术已建立到绝大多数浏览器和Web服务器程序中,因此,仅需在Web服务器端安装服务器证书就可以激活SSL功能了。
如果上述的第一步和第二步已经配置完毕,那么就可以重启Tomcat服务器了,然后从IE浏览器中以HTTPS方式来访问在Tomcat服务器上的任何一个Web应用。现在我们就来访问一下这个地址:
四 、返回一个新的接受任意SSL证书的HttpClient(tomcat中clientAuth="false")
private DefaultHttpClient getIgnoreSSLHttpClient(int sslPort) throws Exception {
httpclient = new DefaultHttpClient();
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers(){
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
System.out.println("server:"+certs[0]);
}
};
sslContext.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme sch = new Scheme("https", sslPort, sf);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
return httpclient;
}
五 、单向验证SSL证书的HttpClient(tomcat中clientAuth="false")
private DefaultHttpClient getOneWayAuthSSLHttpClient(final String ip, int sslPort) throws Exception {
httpclient = new DefaultHttpClient();
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers(){
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
if (certs == null || certs.length == 0)
throw new IllegalArgumentException("null or zero-length certificate chain");
if (authType == null || authType.length() == 0)
throw new IllegalArgumentException("null or zero-length authentication type");
boolean br = false;
for (X509Certificate x509Certificate : certs) {
String issuer = x509Certificate.getIssuerDN().toString();
if(issuer.contains("CN=" + ip)){
br = true;
return;
}
}
if (!br) {
throw new CertificateException("authen failed!");
}
}
};
sslContext.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme sch = new Scheme("https", sslPort, sf);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
return httpclient;
}
六 、双向验证SSL证书的HttpClient(tomcat中clientAuth="true")
Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
同样,Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书
生成key和证书
1)生成服务端私钥,并且导入到服务端KeyStore文件中
keytool -genkey -alias serverkey -keystore serverKey.keystore
2)根据私钥,导出服务端证书
keytool -export -alias serverkey -keystore serverKey.keystore -file server.crt
server.crt就是服务端的证书
3)将服务端证书,导入到客户端的Trust KeyStore中
keytool -import -alias serverkey -file server.crt -keystore serverCrt.keystore
tclient.keystore是给客户端用的,其中保存着受信任的证书
采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中
1)keytool -genkey -alias clientkey -keystore clientKey.keystore
2)keytool -export -alias clientkey -keystore clientKey.keystore -file client.crt
3)keytool -import -alias clientkey -file client.crt -keystore clientCrt.keystore
如此一来,生成的文件分成两组
服务端保存:serverKey.keystore clientCrt.keystore
客户端保存:clientKey.keystore serverCrt.kyestore
client采用clientKey.keystore中的clientkey私钥进行数据加密,发送给server
server采用clientCrt.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,证明消息来自client,进行逻辑处理
server采用serverKey.keystore中的serverkey私钥进行数据叫米,发送给client
client采用serverCrt.kyestore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,证明消息来自server,进行逻辑处理
如果过程中,解密失败,那么证明消息来源错误。不进行逻辑处理。这样就完成了双向的身份认证。
tomcat配置:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="f:\serverKey.keystore" keystorePass="123123" keystoreType="JKS"
truststoreFile="f:\clientCrt.keystore" truststorePass="123123" truststoreType="JKS"
/>
private DefaultHttpClient getMutualAuthSSLHttpClient(int sslPort) throws Exception {
httpclient = new DefaultHttpClient();
String CLIENT_KEY_STORE_PASSWORD = "123123";
String CLIENT_TRUST_KEY_STORE_PASSWORD = "123123";
String CLIENT_KEY_PATH = "clientKey.keystore";//client's private key
String SERVER_CERT_PATH = "serverCrt.keystore";//server's certificate
SSLContext sslContext = SSLContext.getInstance("TSL");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore tks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(CLIENT_KEY_PATH), CLIENT_KEY_STORE_PASSWORD.toCharArray());
tks.load(new FileInputStream(SERVER_CERT_PATH), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
tmf.init(tks);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme sch = new Scheme("https", sslPort, sf);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
return httpclient;
}
参考 :http://www.sunchis.com/html/java/javaweb/2010/0314/71.html
http://www.blogjava.net/stone2083/archive/2007/12/20/169015.html
------------------------------------------------------------
系统需求:
1、
2、
3、
第一步:为服务器生成证书
1、
keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:\home\tomcat.keystore -validity 36500
(参数简要说明:“D:\home\tomcat.keystore”含义是将证书文件的保存路径,证书文件名称是tomcat.keystore ;“-validity 36500”含义是证书有效期,36500表示100年,默认值是90天)
A、输入keystore密码:此处需要输入大于6个字符的字符串
B、“您的名字与姓氏是什么?”这是必填项,并且必须是TOMCAT部署主机的域名或者IP[如:gbcom.com 或者 10.1.25.251](就是你将来要在浏览器中输入的访问地址),否则浏览器会弹出警告窗口,提示用户证书与所在域不匹配。在本地做开发测试时,应填入“localhost”
C、“你的组织单位名称是什么?”、“您的组织名称是什么?”、“您所在城市或区域名称是什么?”、“您所在的州或者省份名称是什么?”、“该单位的两字母国家代码是什么?”可以按照需要填写也可以不填写直接回车,在系统询问“正确吗?”时,对照输入信息,如果符合要求则使用键盘输入字母“y”,否则输入“n”重新填写上面的信息
D、输入<tomcat>的主密码,这项较为重要,会在tomcat配置文件中使用,建议输入与keystore的密码一致,设置其它密码也可以
2、
./keytool -genkey -alias tomcat -keyalg RSA -keystore /usr/local/ac/web/tomcat.keystore -validity 36500
(参数简要说明:“/etc/tomcat.keystore”含义是将证书文件保存在路径/usr/local/ac/web/下,证书文件名称是tomcat.keystore ;“-validity 36500”含义是证书有效期,36500表示100年,默认值是90天)
A、Enter keystore password:此处需要输入大于6个字符的字符串
B、“What is your first and last name?”这是必填项,并且必须是TOMCAT部署主机的域名或者IP[如:gbcom.com 或者 10.1.25.251],就是你将来要在浏览器中输入的访问地址
C、“What is the name of your organizational unit?”、“What is the name of your organization?”、“What is the name of your City or Locality?”、“What is the name of your State or Province?”、“What is the two-letter country code for this unit?”可以按照需要填写也可以不填写直接回车,在系统询问“correct?”时,对照输入信息,如果符合要求则使用键盘输入字母“y”,否则输入“n”重新填写上面的信息
D、Enter key password for <tomcat>,这项较为重要,会在tomcat配置文件中使用,建议输入与keystore的密码一致,设置其它密码也可以
第二步:为客户端生成证书
keytool -genkey -v -alias mykey -keyalg RSA -storetype PKCS12 -keystore D:\home\mykey.p12
对应的证书库存放在“D:\home\mykey.p12”,客户端的CN可以是任意值。双击mykey.p12文件,即可将证书导入至浏览器(客户端)。
第三步:让服务器信任客户端证书
keytool -export -alias mykey -keystore D:\home\mykey.p12 -storetype PKCS12 -storepass password -rfc -file D:\home\mykey.cer
keytool -import -v -file D:\home\mykey.cer -keystore D:\home\tomcat.keystore
keytool -list -keystore D:\home\tomcat.keystore
第四步:让客户端信任服务器证书
keytool -keystore D:\home\tomcat.keystore -export -alias tomcat -file D:\home\tomcat.cer
第四步:配置Tomcat服务器
打开Tomcat根目录下的/conf/server.xml,找到如下配置段,修改如下:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true" maxThreads="150" scheme="https"
secure="true" clientAuth="true" sslProtocol="TLS"
keystoreFile="D:\\home\\test.keystore" keystorePass="123456"
truststoreFile="D:\\home\\test.keystore" truststorePass="123456" />
属性说明:
第五步:测试
在浏览器中输入:https://localhost:8443/,会弹出选择客户端证书界面,点击“确定”,会进入tomcat主页,地址栏后会有“锁”图标,表示本次会话已经通过HTTPS双向验证,接下来的会话过程中所传输的信息都已经过SSL信息加密。
------------------------------------------------------
为tomcat6批量生成安全证书
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。