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的工作原理讀者可以參考下篇文章。