original: http://apps.hi.baidu.com/share/detail/30995314
弄了差不多两天的证书,头都大了 走了很多弯路,把知识拿出来跟大家share下,其实并不复杂。
背景:我们有个WEB服务器,比如TOMCAT,在TOMCAT上我们部署了个应用http://localhost:8080/sslPro, 当我们从浏览器以安全模式,即https访问这个应用时,用到的知识数字证书,数字签名。这里我们只讲到单向认证,即服务器端认证。当我从浏览器访问服务器时,我们的目的是要确认我现在访问的就是localhost上的sslPro,反过来服务器向我证明我就是localhost.
目的:我们要做的事是:用keytool生成证书签名请求,用openssl生成自签名证书,然后模拟CA用自己生成的自签名证书对签名请求进行签名,并把根证书及签名后的证书倒入到KEYSTORE中
准备:J2SDK在目录%JAVA_HOME%/bin提供了密钥库管理工具Keytool,用于管理密钥、证书和证书链。Keytool工具的命令在JavaSE6中已经改变,不过以前的命令仍然支持。Keytool也可以用来管理对称加密算法中的密钥。有关Keytool的知识可以参考:http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/keytool.html。有关openssl的知识请参考:http://www.openssl.org。 下面的准备很重要,(1)把openssl目录下的文件openssl.cnf文件拷贝到openssl的bin目录下,在bin目录下新建目录demoCA、demoCA/certs、demoCA/private、 demoCA/newcerts (2) 在demoCA建立一个空文件 index.txt (3) 在demoCA建立一个文本文件 serial, 没有扩展名,内容是一个合法的16进制数字,例如 0011, 我曾经写过0000,但会导致根证书跟签名证书的序列号都是0,所以不行,建议不写0000。(4) 配置好JDK的环境变量
过程:
a. 生成密钥对
Keytool –genkey –alias test –keystore test.jks 根据提示输入信息,记住:输入的信息必须跟后面的自签名证书信息一致,名字与姓氏我们这里应该输入localhost。 可以用-list查看信息。(到这一步,其实我们可以用export命令导出证书到cer文件,然后把cer文件导入到浏览器,这就是我们自己生成的没有经过签名的证书)
b. 生成证书签名请求
Keytool –certreq –alias test –keystore test.jks –file test.csr。
c. 生成CA的自签名证书
openssl req -new -x509 -keyout root.key -out root.crt -config openssl.cnf 输入信息
d. 把test.csr拷贝到openssl的bin目录下,用CA私钥进行签名(当然也可以到权威机构申请CA签名,但要花很多钱)。
openssl ca -in test.csr -out demo.crt -cert root.crt -keyfile root.key -notext -config openssl.cnf (其中-notext表示不要把证书文件的明文内容输出到文件中去,否则在后面用keytool导入到keystore时会出错。) 。可以用openssl x509 -noout -text -in root.crt 命令查看
e. 导入信任的CA根证书到keystore
keytool -import -v -alias test2 -file root.crt -keystore test.jks
这一步你也可以把根证书倒入到keystore cacerts中,在目录%JAVA_HOME%\jre\lib\security 目录下,有关cacerts的官方资料如下:
The "cacerts" file represents a system-wide keystore with CA certificates. System administrators can configure and manage that file using keytool, specifying "jks" as the keystore type. The initial password of the "cacerts" keystore file is "changeit". 详细信息可参考:http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/keytool.html#cacerts
f. 把CA签名后的证书导入到keystore
keytool -import -v -trustcacerts -alias test –file demo.crt -keystore test.jks
好了,把test.jks拷贝到你应用的WEB-INF目录下。配置tomcat服务器,如下:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystorePass="changeit" keystoreFile="webapps\sslPro\WEB-INF\test.jks
keyAlias="test" "/>
现在当你用HTTPS访问你的应用时,如https://localhost:8443/proTest会出来一个框框,说此证书不在你的信用列表里,问是否信用。这个时候你还有一件事情要做,就是把你信用的根证书导入到你的浏览器中,下次在访问时这个小框框就不会出来了,因为你已经信用它了。
这样自己签名的证书就做好了。写来简单 , 但也花了不少时间。
两个比较好的参考文章:http://zhouzhk.javaeye.com/blog/136943,http://industry.ccidnet.com/art/1078/20030709/53943_2.html
有关SSL的工作原理读者可以参考下篇文章。