https背景(本人學習參考中覺得不錯的幾篇文章)
關於https的個人總結
- 總所周知http是通過明文傳輸的,其不夠安全,傳輸過程中容易被劫持查看傳輸內容甚至修改內容,經常修改內容,用戶經常打開某些網站會有一些奇怪的廣告,這就是因為該網站使用http請求,導致請求內容被修改,新增的廣告。
- https非對稱加密(公鑰私鑰)與對稱加密保證數據安全。
- 代理抓包(中間人攻擊)原理就是通過自己偽造一對公鑰私鑰替代服務器的公鑰私鑰給用戶使用。
- 通過數字證書保證公鑰合法性,避免中間人攻擊。
使用了https,並且證書是由CA機構頒發,Charles抓包還是明文
- 這個問題的原因與證書是由CA機構或者還是自簽證書無關,關鍵在於app端是否對證書進行驗證了,如果對證書沒有進行認證,那么Charles還是會自生成一套證書替代服務端的證書。
App對證書進行校驗,那么如何處理證書過期或者服務端更新證書的問題?
- 證書設計了一個證書鏈的概念,一般證書鏈分三層,頂層為root證書[A]、二級證書[B]、三級證書[C](頒布給用戶),只要A信任B,B信任C,只要客戶端校驗A可信,即C可信,無法被替換。
- 因此客戶端校驗root證書即可,全球信賴的CA的有一百多個,這些基本上都內置到操作系統、瀏覽器中了,這些CA的更新都會由系統來管理,減少客戶端的復雜度。
- 由於系統可以自己導入證書,為防止被人抓取數據分析數據結構,可以使客戶端限制CA證書必須為系統內置的,或者只對某一家CA的證書進行信任。
服務端https配置
將生成私有證書放在classpath下
application.properties中配置
server.port = 443
server.ssl.key-store = classpath:sample.jks
server.ssl.key-store-password = secret
server.ssl.key-password = password
同時支持http
@Bean
public Integer port() {
return 80;
//return SocketUtils.findAvailableTcpPort();
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(createStandardConnector());
return tomcat;
}
private Connector createStandardConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(port());
return connector;
}
http重定向到https
@Value("${server.port}")
private int port;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@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(initiateHttpConnector());
return tomcat;
}
private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(port);
return connector;
}