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;
}