1. 程式人生 > >tomcat部署https,用openssl簽發證書

tomcat部署https,用openssl簽發證書

常見字尾

cer,crt證書(不支援私鑰)
一般是簽署後CA頒發的證書,實質是CA用私鑰在申請者的公鑰上簽名
—–BEGIN CERTIFICATE—–

csr:(Certificate Signing Request) 申請簽名的證書請求
–-BEGIN NEW CERTIFICATE REQUEST–

pfx,p12:(Personal Information Exchange)
儲存證書和私鑰

crl:(Certificate Revocation List)
證書銷燬清單

key,pem:(Privacy-enhanced Electronic Mail)
linux/unix下儲存金鑰的,window下不能用keytool匯出金鑰
—–BEGIN RSA PRIVATE KEY—–
pem同時也能儲存公鑰
—–BEGIN PUBLIC KEY—–

keystore是用來管理各種條目的,包括:
PrivateKeyEntry : 金鑰對
SecretKeyEntry : 私鑰【keystore格式僅為jceks】
TrustedCertificateEntry : 證書
keystore介紹:
Manage keys, certificates and keystores

生成ssl證書

1.用easyRSA,OpenSSL,keytool都可以生成金鑰對
keytool直接是生成金鑰對,無法提取金鑰的,需要用到 java-exportpriv
Tomcat伺服器配置https雙向認證(使用keytool生成證書)


2.直接在免費CA上申請伺服器證書,如CA365

openssl生成方式

  1. 生成CA金鑰
    openssl genrsa -out private/cakey.pem 2048

  2. 生成CA自簽名證書
    openssl req -new -x509 -key private/cakey.pem -out cacert.pem

  3. 生成伺服器的私鑰
    openssl genrsa -out private/pencilboxserver.key 2048

  4. 生成伺服器的簽名請求
    openssl req -new -key private/pencilboxserver.key -out pencilboxcert.csr
    【CommonName設定為自己的域名】

  5. 用CA為伺服器生成簽名的證書
    openssl x509 -req -in pencilboxcert.csr -CA cacert.pem -CAkey private/cakey.pem -CAcreateserial -out pencilboxsigncert.crt -days 730 -sha512

  6. 打包服務端金鑰庫
    openssl pkcs12 -export -in pencilboxsigncert.crt -inkey private/pencilboxserver.key -out pencilboxpsdlib.pfx

  7. 生成客戶端私鑰
    openssl genrsa -out private/client.pem 2048
    ps:如無需實現雙向認證,則無需準備客戶端的東東

  8. 生成客戶端的簽名請求
    openssl req -new -key private/client.pem -out client.csr

  9. 用CA為客戶端生成簽名的證書
    openssl x509 -req -in client.csr -CA cacert.pem -CAkey private/cakey.pem -CAcreateserial -out client.crt

  10. 打包客戶端金鑰庫
    openssl pkcs12 -export -in client.crt -inkey private/client.pem -out client.pfx

keytool匯入

匯入CA證書

keytool -importcert -v -file /Users/pencil-box/Longwei/CA/cacert.pem -keystore /Users/pencil-box/pencilboxserver.keystore 

匯入金鑰對

keytool -importkeystore -v -srckeystore /Users/pencil-box/Longwei/CA/pencilboxpsdlib.pfx -destkeystore /Users/pencil-box/pencilboxserver.keystore

PS:注意keystore是自己建立,或者是用預設的

keytool -genkey -keystore /working/xxx.keystore

Tomcat配置

Tomcat的目錄下,conf目錄下需要更改server.xml和web.xml檔案
server.xml

<Connector SSLEnabled="true" acceptCount="200"              clientAuth="true"
disableUploadTimeout="true" enableLookups="false" maxThreads="125"
port="8443" 
keystoreFile="/Users/pencil-box/Longwei/CA/pencilboxserver.keystore" keystorePass="123456"
truststoreFile="/Users/pencil-box/pencilboxserver.keystore" truststorePass="123456"
protocol="org.apache.coyote.http11.Http11NioProtocol"       scheme="https"
sslProtocol="TLS"
secure="true" />

clientAuth是開啟客戶端驗證的引數

true的時候開啟雙向認證
客戶端需要匯入client.pfx
服務端設定truststoreFile,信任簽發客戶端證書的cacert.pem

keystroeFile是伺服器金鑰對儲存的keystore
truststoreFile是簽署客戶端證書的根證書位置

注意這裡是NIO模式,如果啟用Tomcat APR模式配置中略有不同,詳見mac下tomcat啟用APR模式

web.xml
將下面這段嵌在web-app節點下:

<security-constraint>
<web-resource-collection>
    <web-resource-name>securedapp</web-resource-name>
    <url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

這裡配置了transport-guarantee的引數為confidential,即全網站都是通過ssl加密
web.xml Reference Guide for Tomcat

客戶端配置

匯入簽發伺服器證書的CA自簽證書即可,在這裡是匯入cacert.pem
雙向驗證的時候,還需要匯入client.pfx

如果服務端沒有相應的域名,那麼可以通過改hosts的方式,強行進行域名對映。瀏覽器會匹配域名是否為伺服器證書的Common Name,匹配不成功會報告不安全。

注意事項

  1. 錯誤:
    Caused by: java.security.UnrecoverableKeyException: Cannot recover key
    解決方案:
    修改的key金鑰的密碼與keystore的一致。

  2. 匯入keystore中需要匯入服務端的證書與金鑰打包成的pkcs12檔案,因為keystore不能單獨匯入金鑰。

  3. 簽發證書的時候,要保證CommonName是自己的域名or Ip,
    匹配原則是*.domain.com 只能匹配 ssl.domain.com 不能匹配 ssl1.ssl2.domain.com。

  4. SSL的握手協議可以通過wireshark進行檢視,預設的443埠是直接解析的,非443埠需要配置埠監聽SSL,具體在preferences的RSA keylist裡面。
    對於SSL握手中協商的公鑰演算法,如果使用了Diffie-Hellman演算法,那麼TLS Session Key會用一個動態產生的金鑰對進行加密,並不會使用證書的公鑰,所以即使配置了服務端的金鑰,也是不能解密的。
    詳情可看下面這篇文章。
    如何通過Wireshark檢視HTTPS、HTTP/2網路包(解碼TLS、SSL)
    Is there any particular reason to use Diffie-Hellman over RSA for key exchange?