tomcat設置https的兩種方式
這第一小節的內容參考了文章:https://blog.csdn.net/freeiceflame/article/details/50420059
通常,在創建HTTPS的服務器的時候都需要一個網站的SSL證書文件,但是在網上找到的文檔基本上都是在介紹怎麽自己用keytools創建一個證書,但是這種方法申請的證書根本不會被廣大網民的瀏覽器認證,所以想要創建一個大家都能訪問的HTTPS服務,則從一個受信任的機構去申請一個證書。
?
而從認證網站上下載的證書中並不會包括TOMCAT可以使用的jks證書文件,那麽必須要先將證書轉換為TOMCAT可以使用的格式。假設我們現在已經從CA申請下來了證書文件,也有私鑰文件:
1、example.com.crt:證書文件,裏面已包含自己網站的證書和CA機構的中級證書
2、example.com.key:私鑰文件
?
一、合並證書,生成PKCS12格式的temp.p12文件。會提示你創建密碼(對應tomcat配置文件中的keyPass)。命令行輸入:
openssl pkcs12 -export -in example.com.crt -inkey example.com.key -out temp.p12 -name temp |
?
二、生成jks格式的keystore文件,這個格式的文件可以直接被tomcat識別。需要輸入上一步創建的密碼,及指定新的keystore密碼(對應tomcat配置文件中的keystorePas):
keytool -importkeystore -srckeystore temp.p12 -srcstoretype PKCS12 -destkeystore example.com.jks |
?
三、修改tomcat的server.xml中連接器(Connector)的配置,設置好後重啟tomcat就啟用https了:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Protocol" connectionTimeout="20000" redirectPort="8443" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" keystoreFile="/home/test/tomcat/apache-tomcat-7.0.68/example.com.jks" keyPass="changeit" keystorePass="npzd9zgk" /> |
- protocol:設置用於處理流量的協議,這裏使用的是BIO。詳細解釋見"Tomcat配置文件解析"小節。作為優化,可以考慮改為使用NIO或NIO2(如果支持的話),其它https的設置都是相同的。BIO/NIO/NIO2連接器都是依賴於JSSE SSL來實現https的。如果是使用APR協議的話,https的配置則不相同,見"設置https(APR連接器實現的)"小節。APR是依賴於OpenSSL來實現https的。
- SSLEnabled:啟用HTTPS。
- scheme:可選值為http或https。程序中使用request.getScheme()方法時,會獲取到scheme中指定的值,因此需要傳遞正確的值給程序。
- secure:如果你希望對於該連接器接收到的請求,返回給request.isSecure()方法的調用為true,就設置該值為true。對於SSL連接器,或是正在從SSL加速器(如加密卡)、SSL應用或web服務器接收數據的非SSL連接器,你可能希望將該值設置為true。默認值為false。
- clientAuth:設置是否對客戶端進行HTTPS認證,詳細說明見tomcat官網。默認為false。
- sslProtocol:要使用的SSL協議。默認值是"TLS"。該屬性與sslEnabledProtocols屬性是重疊的。
- sslEnabledProtocols:要使HTTPS支持的SSL協議。如果指定了該值,那麽,只有這裏列出的並且是SSL實施支持的協議才會被啟用。如果未指定該值,JVM默認值會被使用。該屬性與sslProtocol屬性是重疊的。
- keystoreFile:存儲了服務器HTTPS證書的keystore文件的位置。可以使用絕對路徑或相對路徑(相對於CATALINA_BASE)。
- keyPass:用於從指定的keystore文件訪問服務器證書的密碼。默認值是"changeit"。
- keystorePass:用於訪問指定keystore文件的密碼。默認值是keyPass屬性的值。
- keystoreType:keystore文件類型。默認只是"JKS"。
- ciphers:tomcat中加密套件的名稱使用的是"JSSE cipher naming convention"的命名方式。如果使用關鍵字ALL,則可以啟用所有加密套件,但這樣可能是不安全的,所以僅用於測試。下面是經測試過的加密套件,可以保證安全性並兼容大多數客戶端:
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA |
- useServerCipherSuitesOrder:若設定為true,則會強制客戶端按照Server端的加密套件順序來選擇適合的加密套件。僅在tomcat 8及以上版本才支持該選項。
?
設置https(APR連接器實現的)
1、如果按照"設置https"小節,那麽搭建出來的https站點很可能是不兼容Java 6客戶端的,那麽,所有運行在JDK 6上的Java應用程序調用我們https站點的API接口時,都會失敗。這個在https://www.ssllabs.com/網站上可以測試出來:
實際使用運行於Java 6的應用程序調用https站點時,會報類似"javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake"的錯誤信息。這並不是https站點使用的加密套件不兼容Java 6客戶端的原因,而是https站點無法正確處理Java 6客戶端的https握手消息。
?
2、為了解決上面的問題,我們需要使用APR連接器實現的https。APR是依賴於OpenSSL來實現https的,不僅從性能還是功能來說,APR連接器都會比BIO/NIO/NIO2連接器好。在給tomcat配置APR連接器之前,需要先安裝APR和OpenSSL,見"APR的問題"小節。
?
3、修改tomcat的server.xml中連接器(Connector)的配置,設置好後重啟tomcat:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" maxThreads="500" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" SSLProtocol="TLSv1,TLSv1.1,TLSv1.2" SSLCertificateChainFile="/home/test/tomcat/apache-tomcat-7.0.68/CA.crt" SSLCertificateFile="/home/test/tomcat/apache-tomcat-7.0.68/example.com.crt" SSLCertificateKeyFile="/home/test/tomcat/apache-tomcat-7.0.68/example.com.key" SSLCipherSuite="ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA" SSLHonorCipherOrder="true" /> |
- protocol:這裏一定要使用APR連接器協議。下面的SSLProtocol、SSLCertificateFile、SSLCertificateKeyFile等配置都是僅適用於ARP實現的。
- SSLProtocol:要支持的SSL協議。
- SSLCertificateChainFile:包含中級CA證書的文件路徑。證書文件是PEM編碼格式的。
- SSLCertificateFile:包含中級CA證書和網站本身的證書的文件路徑。證書文件是PEM編碼格式的。
- SSLCertificateKeyFile:私鑰文件的路徑。私鑰文件是PEM編碼格式的。
- SSLCipherSuite:加密套件。默認是"HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA"。
- SSLHonorCipherOrder:若設定為true,則會強制客戶端按照Server端的加密套件順序來選擇適合的加密套件。
?
上面有兩個要註意的點:
1) SSLProtocol用於設定要支持的SSL協議。如果給基於OpenSSL的連接器指定超過一個協議,它就會總會支持SSLv2Hello;如果只指定了一個協議,它將不會支持SSLv2Hello。就是這個特性,使得ARP實現的https可以兼容Java 6客戶端。
2) SSLCertificateChainFile指定的文件中只包含中級CA的證書,SSLCertificateFile指定的文件中既包含中級CA的證書也包含網站本身的證書(網站證書在文件中應該放在中級CA證書前面)。這裏是與在nginx中配置https的情況不一樣的。在tomcat中,需要同時指定SSLCertificateChainFile和SSLCertificateFile,否則證書鏈不完整。此時,使用瀏覽器來訪問網站不會有報錯,這可能是因為瀏覽器會自動下載中級CA的證書以構成完整的證書鏈。但是,如果使用Java客戶端程序來調用https站點,可能就會出錯,因為服務器提供的證書鏈是不完整的。SSLCertificateFile中既包含中級CA的證書也包含網站本身的證書,這是因為,像Java 6這種客戶端它是不支持SNI(Server Name Indication)的,所以服務器必須一次性提供所有所需的證書給它,不然的話,若服務器提供的證書只包含網站本身的證書,它會認為證書無效。
?
4、最後的話,如果可能,到https://www.ssllabs.com/ssltest/上面測試下你的https站點,看有無問題。
?
tomcat設置https的兩種方式