SpringBoot配置SSL
一、概念
1、為什麼要使用證書
對資料進行簽名(加密)是我們在網路中最常見的安全操作。簽名有雙重作用,作用一就是保證資料的完整性,證明資料並非偽造,而且在傳輸的過程中沒有被篡改,作用二就是防止資料的釋出者否認其釋出了該資料。
簽名同時使用了非對稱性加密演算法和訊息摘要演算法,對一塊資料簽名時,會先對這塊資料進行訊息摘要運算生成一個摘要,然後對該摘要使用釋出者的私鑰進行加密。 比如微信公眾平臺開發中最常見的呼叫api介面方法是將引數進行字典序排序,然後將引數名和引數值接成一個字串,組合的字串也就相當於我們這裡說的摘要,然後將摘要用平臺金鑰加密。
接收者(客戶端)接受到資料後,先使用釋出者的公鑰進行解密得到原資料的摘要,再對接收到的資料計算摘要,如果兩個摘要相同,則說明資料沒有被篡改。同時,因為釋出者的私鑰是不公開的,只要接收者通過釋出者的公鑰能成功對資料進行解密,就說明該資料一定來源於該釋出者。
那麼怎麼確定某公鑰一定是屬於某釋出者的呢?這就需要證書了。證書由權威認證機構頒發,其內容包含證書所有者的標識和它的公鑰,並由權威認證機構使用它的私鑰進行簽名。資訊的釋出者通過在網路上釋出證書來公開它的公鑰,該證書由權威認證機構進行簽名,認證機構也是通過釋出它的證書來公開該機構的公鑰,認證機構的證書由更權威的認證機構進行簽名,這樣就形成了證書鏈。證書鏈最頂端的證書稱為根證書,根證書就只有自簽名了。總之,要對網路上傳播的內容進行簽名和認證,就一定會用到證書。關於證書遵循的標準,最流行的是 X.509
2、SSL協議
SSL(Secure Socket Layer,安全套接層):是為網路通訊提供安全及資料完整性的一種安全協議。SSL位於TCP/IP協議與各種應用層協議之間,為資料通訊提供安全支援。SSL協議分為兩層:1)SSL記錄協議,建立在可靠的傳輸協議(如TCP)之上,為高層協議提供資料封裝、壓縮、加密等基本功能的支援;2)SSL握手協議,建立在SSL記錄協議之上,用於在實際資料傳輸開始前,通訊雙方進行身份認證、協商加密演算法、交換加密金鑰等。
二、SpringBoot配置SSL
1、生成證書
keytool -genkey -alias tomcat -keyalg RSA -keystore /Users/zhanghao/Desktop/tomcatkeystore.keystore -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass 123qwe
引數說明:
-genkey:表示要建立一個新的金鑰
-alias:和keystore關聯的別名,這個alias通常不區分大小寫,預設“mykey”
-keyalg:使用加密的演算法,這裡是RSA,預設“DSA”
-keystore:金鑰儲存的檔案位置,預設“使用者宿主目錄中名為 .keystore 的檔案,沒有不會新建,所以還是指定的好”
-dname:表明了金鑰的發行者身份
CN=commonName 注:生成證書時,CN要和伺服器的域名相同,如果在本地測試,則使用localhost
OU=organizationUnit
O=organizationName
L=localityName
S=stateName
C=country
-keypass:私有金鑰的密碼,這裡設定為“123qwe”
其他引數
-storepass :存取密碼(我用的mac jdk1.8.0_131 不支援這個引數)
-validity:金鑰的有效期,預設為90天(我用的mac jdk1.8.0_131 不支援這個引數)
-keysize 1024(沒用過)
-file 讀時為標準輸入,寫時為標準輸出 (沒用過)
注:cacerts證書檔案(The cacerts Certificates File),存在於$JAVA_HOME\jre\lib\security目錄下,是Java系統的CA證書倉庫
2、SpringBoot配置SSL
1)將證書檔案複製到專案的根目錄
2)配置檔案
server:
port: 8080
ssl:
key-store: tomcatkeystore.keystore
key-store-password: 123qwe
key-store-type: JKS
key-alias: tomcat
http訪問
https訪問
3、配置http自動轉向https
1)埠配置
http:
port: 8080
server:
port: 8443
2)埠監聽轉換
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.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpsConfig {
@Value("${http.port}")
private int httpPort;
@Value("${server.port}")
private int serverPort;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory () {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(serverPort);
return connector;
}
}
請求http://localhost:8080則自動重定向到https://localhost:8443