本文試圖以通俗易通的方式介紹Https的工作原理,不糾結具體的術語,不考證嚴格的流程。我相信弄懂了原理之后,到了具體操作和實現的時候,方向就不會錯,然后條條大路通羅馬。閱讀文本需要提前大致了解對稱加密、非對稱加密、信息認證等密碼學知識。如果你不太了解,可以閱讀Erlang發明人Joe Armstrong最近寫的Cryptography Tutorial。大牛出品,通俗易懂,強力推薦。
Https涉及到的主體
- 客戶端。通常是瀏覽器(Chrome、IE、FireFox等),也可以自己編寫的各種語言的客戶端程序。
- 服務端。一般指支持Https的網站,比如github、支付寶。
- CA(Certificate Authorities)機構。Https證書簽發和管理機構,比如Symantec、Comodo、GoDaddy、GlobalSign。
下圖里我畫出了這幾個角色:
發明Https的動機
- 認證正在訪問的網站。什么叫認證網站?比如你正在訪問支付寶,怎樣確定你正在訪問的是阿里巴巴提供的支付寶而不是假冒偽劣的釣魚網站呢?
- 保證所傳輸數據的私密性和完整性。眾所周知,Http是明文傳輸的,所以處在同一網絡中的其它用戶可以通過網絡抓包來竊取和篡改數據包的內容,甚至運營商或者wifi提供者,有可能會篡改http報文,添加廣告等信息以達到盈利的目的。
Https的工作流程
這一節通過介紹Https協議的工作流程,來說明Https是如何達成自己的兩個目的的。下圖我畫出了Https的工作流程,注意,這只是原理示意圖,並不是詳細的協議解析。
可以看到工作流程,基本分為三個階段:
-
認證服務器。瀏覽器內置一個受信任的CA機構列表,並保存了這些CA機構的證書。第一階段服務器會提供經CA機構認證頒發的服務器證書,如果認證該服務器證書的CA機構,存在於瀏覽器的受信任CA機構列表中,並且服務器證書中的信息與當前正在訪問的網站(域名等)一致,那么瀏覽器就認為服務端是可信的,並從服務器證書中取得服務器公鑰,用於后續流程。否則,瀏覽器將提示用戶,根據用戶的選擇,決定是否繼續。當然,我們可以管理這個受信任CA機構列表,添加我們想要信任的CA機構,或者移除我們不信任的CA機構。
-
協商會話密鑰。客戶端在認證完服務器,獲得服務器的公鑰之后,利用該公鑰與服務器進行加密通信,協商出兩個會話密鑰,分別是用於加密客戶端往服務端發送數據的客戶端會話密鑰,用於加密服務端往客戶端發送數據的服務端會話密鑰。在已有服務器公鑰,可以加密通訊的前提下,還要協商兩個對稱密鑰的原因,是因為非對稱加密相對復雜度更高,在數據傳輸過程中,使用對稱加密,可以節省計算資源。另外,會話密鑰是隨機生成,每次協商都會有不一樣的結果,所以安全性也比較高。
-
加密通訊。此時客戶端服務器雙方都有了本次通訊的會話密鑰,之后傳輸的所有Http數據,都通過會話密鑰加密。這樣網路上的其它用戶,將很難竊取和篡改客戶端和服務端之間傳輸的數據,從而保證了數據的私密性和完整性。
使用Https的流程
如果你是一個服務器開發者,想使用Https來保護自己的服務和用戶數據安全,你可以按照以下流程來操作。
總結
- 說是討論Https,事實上Https就是Http跑在SSl或者TLS上,所以本文討論的原理和流程其實是SSL和TLS的流程,對於其它使用SSL或者TLS的應用層協議,本文內容一樣有效。
- 本文只討論了客戶端驗證服務端,服務端也可以給客戶端頒發證書並驗證客戶端,做雙向驗證,但應用沒有那么廣泛,原理類似。
- 由於采用了加密通訊,Https無疑要比Http更耗費服務器資源,這也是很多公司明明支持Https卻默認提供Http的原因。
1- 使用HTTPS連接器,需要生成一份Certificate keystore,用於加密和機密瀏覽器的SSL溝通
# windows:
keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "d:\\1.keystore"
# linux:
keytool -genkey -alias tomcat -keyalg RSA
# 執行完上述命令后在home目錄下多了一個新的.keystore文件
2- 新增屬性文件 tomcat.https.properties
類比
<!-- Define an SSL HTTP/1.1 Connector on port 443 --> <Connector className="org.apache.catalina.connector.http.HttpConnector" port="443" minProcessors="5" maxProcessors="75" keystoreFile="path.to.keystore" enableLookups="true" acceptCount="10" debug="0" scheme="https" secure="true"> <Factory className="org.apache.catalina.net.SSLServerSocketFactory" clientAuth="false" protocol="TLS" keystorePass="keystore.password"/> </Connector>
custom.tomcat.https.port=443 custom.tomcat.https.secure=true custom.tomcat.https.scheme=https custom.tomcat.https.ssl=true custom.tomcat.https.keystore=d:\\1.keystore custom.tomcat.https.keystore-password=xinli2016
import java.io.File; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @PropertySource("classpath:/tomcat.https.properties") @EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class) public class WebConfiguration extends WebMvcConfigurerAdapter { @Bean public EmbeddedServletContainerFactory servletContainer(TomcatSslConnectorProperties properties) { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { // SecurityConstraint必須存在,可以通過其為不同的URL設置不同的重定向策略。 SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); securityConstraint.addCollection(collection); context.addConstraint(securityConstraint); } }; tomcat.addAdditionalTomcatConnectors(createSslConnector(properties)); return tomcat; } private Connector createSslConnector(TomcatSslConnectorProperties properties) { Connector connector = new Connector(); properties.configureConnector(connector); return connector; } @ConfigurationProperties(prefix = "custom.tomcat.https") public static class TomcatSslConnectorProperties { private Integer port; private Boolean ssl = true; private Boolean secure = true; private String scheme = "https"; private File keystore; private String keystorePassword; // 省略 get set public void configureConnector(Connector connector) { if (port != null) { connector.setPort(port); } if (secure != null) { connector.setSecure(secure); } if (scheme != null) { connector.setScheme(scheme); } if (ssl != null) { connector.setProperty("SSLEnabled", ssl.toString()); } if (keystore != null && keystore.exists()) { connector.setProperty("keystoreFile", keystore.getAbsolutePath()); connector.setProperty("keystorePass", keystorePassword); } } } }
https://my.oschina.net/freegarden/blog/609975
下面生成的 .keystore文件也可以用 .jks 后綴代替,
jks 的意思就是 Java keystore, 另外需要知道
.cer文件是二進制的,
.pem文件是文本文件, 本質都是一樣的, 他們可以互相轉換。
java 語言操作的是二進制的文件, 其他的一些腳本語言, 可能操作的是PEM格式的文件。看具體情況吧。
創建服務端keystore
keytool -genkey -v -alias server_ks -keysize 2048 -keyalg RSA -dname "CN=www.abc.com" -keypass 123456 -storepass 123456 -keystore ./server.keystore -validity 36500
創建客戶端keystore
keytool -genkey -v -alias client_ks -keysize 2048 -keyalg RSA -dname "CN=www.abc.com" -keypass 123456 -storepass 123456 -keystore ./client.keystore -validity 36500
導出服務端證書
keytool -export -v -alias server_ks -keystore ./server.keystore -storepass 123456 -file ./server.cer
導出客戶端證書
keytool -export -v -alias client_ks -keystore ./client.keystore -storepass 123456 -file ./client.cer
將服務端證書導入到客戶端trustkeystroe
keytool -import -v -alias xxx -keystore ./clientTrust.jks -storepass 123456 -file ./server.cer
將客戶端證書導入到服務端trustkeystroe
keytool -import -v -alias xxx -keystore ./serverTrust.jks -storepass 123456 -file ./client.cer
把二進制的CER文件轉換為文本的PEM文件
openssl x509 -in ./xxx.cer -inform der -outform pem -out ./xxx.pem
把文本的PEM文件轉換為二進制的CER文件
openssl x509 -in ./xxx.pem -inform pem -outform der -out ./xxx.cer
jks文件(java key store文件)轉化為瀏覽器可以加載的PKCS12格式
keytool -importkeystore -srckeystore ./client.keystore -destkeystore ./browser.p12 -srcstoretype JKS -deststoretype PKCS12 -keypass 123456 -storepass 123456
storetype 類型有 JKS, JCEKS, PKCS12, PKCS11 and DKS
下面的命令查看證書是否已經添加到信任列表中了
keytool -list -keystore ./serverTrust.jks
http://blog.csdn.net/langeldep/article/details/54772736
import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.SocketUtils; /** * Created by tangcheng on 5/28/2017. */ @Configuration public class SslConfig { @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { // SecurityConstraint必須存在,可以通過其為不同的URL設置不同的重定向策略。 SecurityConstraint constraint = new SecurityConstraint(); constraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); constraint.addCollection(collection); context.addConstraint(constraint); } }; tomcat.addAdditionalTomcatConnectors(httpConnector()); return tomcat; } @Bean public Connector httpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); //Connector監聽的http的端口號 connector.setPort(80); connector.setSecure(false); //監聽到http的端口號后轉向到的https的端口號 connector.setRedirectPort(8443); return connector; } @Bean public Integer port() { return SocketUtils.findAvailableTcpPort(); } }
http://www.cnblogs.com/xxt19970908/p/6736370.html
瀏覽器的地址欄中顯示不安全:因為這個證書是不收信任的,傳統一般都企業都是需要購買此證書的
http://www.cnblogs.com/xxt19970908/p/6736370.html
https://github.com/spring-projects/spring-boot/blob/v1.5.3.RELEASE/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors/src/main/java/sample/tomcat/multiconnector/SampleTomcatTwoConnectorsApplication.java
http://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/htmlsingle/#howto-configure-ssl
http://www.cnblogs.com/xinzhao/p/4952856.html
http://www.cnblogs.com/xinzhao/p/4950689.html
證書頒發機構
- CA機構私鑰
openssl genrsa -out ca.key 2048
- CA證書
openssl req -x509 -new -key ca.key -out ca.crt
注意生成過程中需要輸入一些CA機構的信息
服務端
- 生成服務端私鑰
openssl genrsa -out server.key 2048
- 生成服務端證書請求文件
openssl req -new -key server.key -out server.csr
注意生成過程中需要你輸入一些服務端信息
- 使用CA證書生成服務端證書
openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt
關於sha256,默認使用的是sha1,在新版本的chrome中會被認為是不安全的,因為使用了過時的加密算法。
- 打包服務端的資料為pkcs12格式(非必要,只是換一種格式存儲上一步生成的證書)
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pkcs12
生成過程中,需要創建訪問密碼,請記錄下來。
- 生成服務端的keystore(.jks文件, 非必要,Java程序通常使用該格式的證書)
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12
生成過程中,需要創建訪問密碼,請記錄下來。
- 把ca證書放到keystore中(非必要)
keytool -importcert -keystore server.jks -file ca.crt
客戶端
- 導入根證書ca.crt到瀏覽器受信任的根證書頒發機構列表中
不管通過什么瀏覽器吧,總之你要找到下面這個頁面,點擊導入,將上面生成的CA機構的ca.crt導入到收信任的根證書頒發機構列表中。
注意,收信任的根證書頒發機構列表是操作系統級的,不管通過哪個瀏覽器進入配置,都是只需要配置一次,再使用其它瀏覽器時,無需重復配置。
Spring Boot
Spring Boot為web容器提供了統一的抽象配置,不管你使用的是Tomcat是Jetty還是其它web容器,如果要在Spring Boot中使用Https,你只需要在你的配置類中,添加如下代碼,注冊一個EmbeddedServletContainerCustomizer Bean即可。
需要用到上面生成的Server.jks文件
@Configuration public class WebConfig { @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { Ssl ssl = new Ssl(); ssl.setKeyStore("Server.jks"); ssl.setKeyStorePassword("passwd"); container.setSsl(ssl); container.setPort(8443); } }; } }
Nginx
如果要在Nginx中使用Https,需要用到上面生成的Server.crt,Server.key。
server { listen 127.0.0.1:443 ssl; ssl on; ssl_certificate Server.crt; ssl_certificate_key Server.key; #省略無關配置... }
總結
crt、jks、pkcs12都是用來保存證書的不同格式,不同的服務器軟件可能會使用不同格式的證書文件。
OpenSSl、Keytool都是可以用來生成Https證書的工具軟件,其中OpenSSl功能更多更復雜,Keytool隨JDK安裝而安裝。
證書的格式是多樣的,生成證書的軟件工具有很多,不同服務器程序的配置方法不盡相同,要達成目的有很多種方法。所以,重要的是弄懂原理,而不是按照教程一步一步敲命令。
跟白話Https一樣,本文仍然沒有介紹服務端怎么驗證客戶端,但如果你弄懂了原理,我想你已經可以自己去實現了。
http://www.cnblogs.com/xinzhao/p/4950689.html
前言:
因為公司項目客戶要求使用HTTPS的方式來保證數據的安全,所以木有辦法研究了下怎么生成ssl證書來使用https以保證數據安全。
百度了不少資料,看到JAVA的JDK自帶生成SSL證書的工具:keytool,外加看了同事的心得體會,自己總結了一下具體的使用方法和使用過程中發現的問題及解決辦法。
1:什么是HTTPS?
HTTPS其實是有兩部分組成:HTTP + SSL / TLS,
也就是在HTTP上又加了一層處理加密信息的模塊,並且會進行身份的驗證。
問題:
Firebug和postman之類的瀏覽器調試工具,為什么獲取到的是明文?
解答:
SSL是對傳輸的數據進行加密,針對的是傳輸過程的安全。
firebug之類的瀏覽器調試工具,
因為他們得到的是客戶端加密之前/解密之后的數據,因此是明文的。
2:什么是自簽名證書?
就是自己生成的證書,並不是官方生成的證書。
除非是很正式的項目,否則使用自己簽發的證書即可,因為官方生成證書是要花錢滴。
3:進入正題,使用JDK自帶工具KeyTool 生成自簽發證書!
第一步:為服務器生成證書
打開CMD命令行工具,cd到C盤根目錄或者是jdk的bin目錄下,如下圖所示:
使用keytool命令生成證書:
keytool
-genkey
-alias tomcat(別名)
-keypass 123456(別名密碼)
-keyalg RSA(算法)
-keysize 1024(密鑰長度)
-validity 365(有效期,天單位)
-keystore D:/keys/tomcat.keystore(指定生成證書的位置和證書名稱)
-storepass 123456(獲取keystore信息的密碼)
方便復制版:
keytool -genkey -alias tomcat -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore D:/keys/tomcat.keystore -storepass 123456
圖例:
回車執行后如下圖:
點擊回車即可在D:/keys/文件夾內生成名為:tomcat.keystore的文件。
成功后無提示信息
注意:
①D:/keys/ 目錄需要提前手動創建好,否則會生成失敗
②提示輸入域名的時候不能輸入IP地址
問題①的錯誤信息如下:
第二步:為客戶端生成證書
為瀏覽器生成證書,以便讓服務器來驗證它。
為了能將證書順利導入至IE和Firefox,證書格式應該是PKCS12,
因此,使用如下命令生成:
keytool
-genkey
-alias client
-keypass 123456
-keyalg RSA
-storetype PKCS12
-keypass 123456
-storepass 123456
-keystore D:/keys/client.p12
方便復制版:
keytool -genkey -alias client1 -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -storetype PKCS12 -keystore D:/keys/client1.p12 -storepass 123456
圖例:
第二步余下操作步驟同第一步。
第三步:讓服務器信任客戶端證書
1、
由於不能直接將PKCS12格式的證書庫導入,
必須先把客戶端證書導出為一個單獨的CER文件,使用如下命令:
keytool -export -alias client -keystore D:/keys/client.p12 -storetype PKCS12 -keypass 123456 -file D:/keys/client.cer
注意:
Keypass:指定CER文件的密碼,但會被忽略,而要求重新輸入
2、
將該文件導入到服務器的證書庫,添加為一個信任證書:
keytool -import -v -file D:/keys/client.cer -keystore D:/keys/tomcat.keystor
e -storepass 123456
圖例:
完成之后通過list命令查看服務器的證書庫,
可以看到兩個證書,一個是服務器證書,一個是受信任的客戶端證書:
keytool -list -v -keystore D:/keys/tomcat.keystore
第四步:讓客戶端信任服務器證書
1、
由於是雙向SSL認證,客戶端也要驗證服務器證書,
因此,必須把服務器證書添加到瀏覽器的“受信任的根證書頒發機構”。
由於不能直接將keystore格式的證書庫導入,
必須先把服務器證書導出為一個單獨的CER文件,使用如下命令:
keytool -keystore D:/keys/tomcat.keystore -export -alias tomcat6 -file D:/keys/server.cer
2、
雙擊server.cer文件,按照提示安裝證書,
將證書填入到“受信任的根證書頒發機構”。
填入方法:
打開瀏覽器 - 工具 - internet選項-內容- 證書-把中級證書頒發機構里的www.localhost.com(該名稱即時你前面生成證書時填寫的名字與姓氏)證書導出來-再把導出來的證書導入 受信任的根頒發機構 就OK了。
第五步:配置Tomcat服務器
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
clientAuth="true"
sslProtocol="TLS"
keystoreFile="D:/keys/tomcat.keystore"
keystorePass="123456"
truststoreFile="D:/keys/tomcat.keystore"
truststorePass="123456" />
屬性說明:
clientAuth:設置是否雙向驗證,默認為false,設置為true代表雙向驗證
keystoreFile:服務器證書文件路徑
keystorePass:服務器證書密碼
truststoreFile:用來驗證客戶端證書的根證書,此例中就是服務器證書
truststorePass:根證書密碼
注意:
① 設置clientAuth屬性為True時,需要手動導入客戶端證書才能訪問。
② 要訪問https請求 需要訪問8443端口,訪問http請求則訪問Tomcat默認端口(你自己設置的端口,默認8080)即可。
總結:
經過以上五步,你使用HTTPS 端口為8443 進行訪問的時候 就是經過SSL信息加密,不怕被截獲了。
通話的雙方,必須是都擁有證書的端,才能進行會話,換句話說,就是只有安裝了咱證書的客戶端,才能與服務器通信。
小貼士:
強制 https 訪問
在 tomcat /conf/web.xml 中的 </welcome- file-list> 后面加上這
- <login-config>
- <!-- Authorization setting for SSL -->
- <auth-method>CLIENT-CERT</auth-method>
- <realm-name>Client Cert Users-only Area</realm-name>
- </login-config>
- <security-constraint>
- <!-- Authorization setting for SSL -->
- <web-resource-collection >
- <web-resource-name >SSL</web-resource-name>
- <url-pattern>/*</url-pattern>
- </web-resource-collection>
- <user-data-constraint>
- <transport-guarantee>CONFIDENTIAL</transport-guarantee>
- </user-data-constraint>
- </security-constraint>
完成以上步驟后,在瀏覽器中輸入http的訪問地址也會自動轉換為https了。
附錄1:
keytool常用命令
-alias 產生別名
-keystore 指定密鑰庫的名稱(就像數據庫一樣的證書庫,可以有很多個證書,cacerts這個文件是jre自帶的,
你也可以使用其它文件名字,如果沒有這個文件名字,它會創建這樣一個)
-storepass 指定密鑰庫的密碼
-keypass 指定別名條目的密碼
-list 顯示密鑰庫中的證書信息
-v 顯示密鑰庫中的證書詳細信息
-export 將別名指定的證書導出到文件
-file 參數指定導出到文件的文件名
-delete 刪除密鑰庫中某條目
-import 將已簽名數字證書導入密鑰庫
-keypasswd 修改密鑰庫中指定條目口令
-dname 指定證書擁有者信息
-keyalg 指定密鑰的算法
-validity 指定創建的證書有效期多少天
-keysize 指定密鑰長度
使用說明:
導入一個證書命令可以如下:
keytool -import -keystore cacerts -storepass 666666 -keypass 888888 -alias alibabacert -file C:\alibabajava\cert\test_root.cer
其中-keystore cacerts中的cacerts是jre中默認的證書庫名字,也可以使用其它名字
-storepass 666666中的666666是這個證書庫的密碼
-keypass 888888中的888888是這個特定證書的密碼
-alias alibabacert中的alibabacert是你導入證書的別名,在其它操作命令中就可以使用它
-file C:\alibabajava\cert\test_root.cer中的文件路徑就是要導入證書的路徑
瀏覽證書庫里面的證書信息,可以使用如下命令:
keytool -list -v -alias alibabacert -keystore cacerts -storepass 666666
要刪除證書庫里面的某個證書,可以使用如下命令:
keytool -delete -alias alibabacert -keystore cacerts -storepass 666666
要導出證書庫里面的某個證書,可以使用如下命令:
keytool -export -keystore cacerts -storepass 666666 -alias alibabacert -file F:\alibabacert_root.cer
要修改某個證書的密碼(注意:有些數字認證沒有私有密碼,只有公匙,這種情況此命令無效)
這個是交互式的,在輸入命令后,會要求你輸入密碼
keytool -keypasswd -alias alibabacert -keystore cacerts
這個不是交互式的,輸入命令后直接更改
Keytool -keypasswd -alias alibabacert -keypass 888888 -new 123456 -storepass 666666 -keystore cacerts
http://www.cnblogs.com/green-hand/p/6514597.html
1 SSL單向認證概念
當客戶端(服務請求方)向服務端(服務提供方)發起請求時,服務器端需要向客戶端提供認證。服務端需要生成一個keystore和一個服務器密鑰對兒(公鑰和私鑰),客戶端需要生成一個truststore,然后導入服務端的公鑰證書。
2 keystore以及服務器密鑰對兒的生成
keytool -genkeypair -alias certificatekey -keyalg RSA -validity 365 -keystore shfqkeystore.jks
這條命令會在生成keystore后接着生成一個密鑰對兒。RSA是非對稱密鑰算法,也可以改為 keytool支持的其他密鑰算法,365代表的是證書的有效期,可以自己指定,shfqkeystore.jks是keystroe的名稱,也可以自己指定。打開cmd命令行,輸入:
keytool -genkeypair -alias certificatekey -keyalg RSA -validity 365 -keystore shfqkeystore.jks
會提示輸入keystore的密碼,接着會提示輸入名字等信息,如下圖:
補充:輸入<certificatekey>的主密碼,是指生成服務端證書的私鑰。服務端私鑰如果和keystore的相同的話,直接按回車。建議直接按回車,即服務端私鑰和keystore的密碼相同。如果兩者的密碼不相同的話在服務端tomcat server.xml中配置完畢以后啟動tomcat會報一個UnrecoverableKeyException: Cannot recover key的異常(后面會介紹服務端 tomcat server.xml 的配置的)。
keytool會把生成的keystore文件默認保存到C:\Users\lenovo路徑下(用戶目錄下的計算機名稱下)接下來生成的所有文件也都保存到此處。
3 驗證新生成的keystor文件以及證書信息
可以執行下面的命令:
keytool -list -v -keystore shfqkeystore.jks
會顯示出以下信息,如圖:
4 導出公鑰證書
下面的命令可以導出自簽公鑰證書:
keytool -export -alias certificatekey -keystore shfqkeystore.jks -rfc -file shfqcert.cer
其中shfqcert.cer是導出證書的名稱,可以隨便起個名字,shfqkeystore.jks是2中生成的keystore 文件。
執行上面的命令會要求輸入shfqkeystore的密碼,會顯示以下信息,如下圖。
5 Truststore的生成以及公鑰證書的導入
把4生成的公鑰證書shfqcert.cer導入到truststore中
Keytool -import -alias certificatekey -file shfqcert.cer -keystore
shfqtruststore.jks
shfqcert.cer是4導出的公鑰證書,shfqtruststore.jks可以隨便起,是生成的truststore的文件名。這條命令首先會生成一個truststore,然后導入4生成的公鑰證書shfqcert.cer。
執行keytool -import -alias certificatekey -file shfqcert.cer -keystore shfqtruststore.jks后,首先會提示輸入truststore的密碼,如下圖:
6 驗證5生成的truststore文件
keytool -list -v -keystore shfqtruststore.jks
shfqtruststore.jks是5生成的truststore文件名。
到此為止,keystore、truststore、公鑰證書都已生成完畢。
7 配置服務端的tomcat
找到tomcat安裝路徑下的conf路徑下的server.xml文件
打開server.xml,找到
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
這樣一段注釋,在這段注釋下面添加如下一段代碼:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false"
disableUploadTimeout="true"
enableLookups="false" maxThreads="25"
port="8443" keystoreFile="D:\developTools\apache-tomcat-idm\tomcat.keystore" keystorePass="111111"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />
其中clientAuth=”false”表示是SSL單向認證,即服務端認證,port=”8443”是https的訪問端口,keystoreFile="D:\developTools\apache-tomcat-idm\tomcat.keystore"是第一步中生成的keystore的保存路徑,keystorePass="111111"是第一步生成的keystore的密碼。
到此服務器端已經配置完畢,為了驗證是否已經配置正確,我們可以在瀏覽器中進行驗證。首先啟動tomcat,然后在瀏覽器地址輸入欄中輸入:https://localhost:8443
如果看到如下截圖的一個頁面則表示服務端已經配置成功了。
之所以會出現“該網站的安全證書不受信任!”的警告是因為證書是自己簽發的而不是一個權威的CA機構簽發的。
最后還得在hosts文件中配置自己的IP地址,把IP地址映射為一個common name,這個common name就是您在第2步中生成服務器證書時候的“您的名字與姓氏是什么?”輸入的名字。
8 客戶端配置
在客戶端配置服務端的地址時要注意:比如 https://shifengqiang:8443/syn/Users
這個地址協議格式是https主機名是shifengqiang,這個shifengqiang就是在第2步中生成服務器端證書時要求輸入的“您的名字與姓氏是什么?”名字。8443是https協議默認的端口。
在客戶端向服務器端同步代碼前面加入這樣一段代碼:
System.setProperty("Java.protocol.handler.pkgs", "com.sun.NET.ssl.internal.www.protocol");
System.setProperty("java.protocol.handler.pkgs", "com.ibm.Net.ssl.internal.www.protocol");
String trustStorePath =
“D:\developTools\apache-tomcat-idm\shfqtruststore.jks”;
String trustStorePassword = “client”;
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
其中trustStorePath 是truststore的路徑,trustStorePassword 是truststore的密碼。至此單向SSL配置完畢。
參考鏈接:http://zjumty.iteye.com/blog/1885356
http://blog.csdn.net/shfqbluestone/article/details/21242323