HTTP 与 HTTPS区别
首先,来简单了解一下 HTTP 与 HTTPS 吧。
超文本传输协议 HTTP 协议被用于在 Web 浏览器和网站服务器之间传递数据。HTTP 协议是以明文方式发送数据,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此 HTTP 协议不适合传输一些敏感信息,比如信用卡号、密码等信息。
为了解决 HTTP 协议的这一缺陷,需要使用另一种传输协议:安全套接字层超文本传输协议,也就是 HTTPS 协议。为了数据传输的安全,HTTPS 在HTTP 的基础上加入了 SSL 协议,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密(具体加密原理这里不赘述)。
两者的区别主要为以下四点:
1、https 协议需要到申请 ssl 证书,现在,免费的ssl证书申请机构不少,个人网站使用完全没问题(文末列出几个提供免费证书的网站);
2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议;
3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443;
4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
目前,很多网站都开始启用 HTTPS 协议进行数据传输,这也是保证数据传输安全的一种方式。那么,当我们搭建自己的网站的时候应该怎么启用 HTTPS 呢?下面将介绍如何在 SpringBoot 项目中添加 HTTPS 支持。
KeyTool 生 成自签发证书文件
1、在控制台输入以下命令开始 生成自签发证书
keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore MyKeyStore.p12 -validity 36500
关键参数说明:
-
-storetype 指定密钥仓库类型
-
-keyalg 生证书的算法名称,RSA是一种非对称加密算法
-
-keysize 证书大小
-
-keystore 生成的证书文件的存储路径(可指定相对路径或绝对路径)
-
-validity 证书的有效期(天 为单位)
2、其他设置
然后一路操作,输入相应的设置, 最后在确认是否正确的时候,检查输入的值是否正确,是就输入y 进行确认。
控制台输入以下命令查看密钥库中的信息
keytool -list -v -keystore MyKeyStore.p12 -storepass chengblog
显示结果,可以看到密钥库中已经存有了一个条目
输入 y 确认设置之后,keytool 工具在设置路径下生成 MyKeyStore.p12 文件,当填写文件名称,会在存储在相对路径下,也就是控制台定位到的目录下。将该文件拷贝到项目根目录下。
项目整合
在 application.properties 配置文件中添加以下配置项:
# 端口
http.port=8080
server.port=443
# 指定签名文件,对应生成的密钥库文件
server.ssl.key-store=classpath:MyKeyStore.p12
# 指定签名密码,设置的密钥库指令
server.ssl.key-store-password=chengblog
# 指定密钥仓库类型,PKCS12
server.ssl.keyStoreType=PKCS12
# 指定别名,生成密钥库的时候进行了设定
server.ssl.keyAlias=tomcat
重启项目,然后就可以进行访问了
https://localhost:443/login/page
然而访问网站的人并不知道网站使用了 HTTPS 协议,当访问 http://localhost:8080 时就需要进行自动跳转,我们可以添加配置类来实现自动跳转。
https 配置类代码 HttpsConfig.java,需要在全局配置类中引用入该类。
package com.wenlincheng.cblog.config;
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;
/**
* @ClassName: HttpsConfig
* @Description: 配置https
* @Author: Cheng
* @Date: 2018/9/17 23:29
* @Version: 1.0.0
*/
public class HttpsConfig {
// 监听的http请求的端口 http.port=端口号 如8080
@Value("${http.port}")
Integer httpPort;
//https端口 如443
@Value("${server.port}")
Integer httpsPort;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
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");
//表示用 8080 端口来供http访问
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
//自动重定向到 https 端口 默认为8443 这里设置为443 因为与SVN Server 端口冲突了
connector.setRedirectPort(httpsPort);
return connector;
}
}
解决 Mixed Content 错误
开启 HTTPS 之后,如果在页面中引入了 HTTP 资源,比如这里引入了百度分享的 share.js 文件,由于是 http请求的资源,会被直接 block 掉,造成引入失败,报 Mixed Content (混合内容) 错误。
这里介绍一种最简单的解决方法,在页面的 <head></head> 中加入以下代码,浏览器会自动将 http 的请求升级为 https 请求。针对引入该资源,我项目中采用的是直接将百度分享的资源进行本地化,因为百度分享并不支持 https,就算进行请求升级也无能为力。
<#-- 将 http 请求 安全升级为 https -->
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
免费申请 SSL 证书网站推荐:
Let's Encrypt
网站: https://letsencrypt.org/
阿里云Symantec DV SSL
网站:https://common-buy.aliyun.com/?commodityCode=cas
腾讯云DV SSL 证书
网站:https://cloud.tencent.com/product/ssl
扫码关注