一句话归纳:如今网站访问基本都须要使用https访问,不然浏览器就会报不安全提示,本文针对springboot+apache先后端分离的项目的https设置与部署进行说明。html
当前访问互联网上的应用,基本都使用https了,不然浏览器会提示不安全,存在信息安全风险,还影响用户体验。最近公司须要对当前http访问的项目进行https部署,当前项目是使用先后端分离,后端使用springboot,前端使用apache,本文将对部署过程进行记录,并对https及相关知识作一下梳理,主要包括如下内容:前端
使用http已经能够完成功能,为何还须要使用https,缘由是使用http传输的内容是明文的,明文的数据传输容易被拦截,形成数据容易被修改,数据内容容易泄露的危险,如何解决这种不安全问题,固然是须要对数据进行加密传输,因而,就有了https。https是Hyper Text Transfer Protocol over Secure Socket Layer
的缩写,表示安全的超文本传输协议,它基于SSL/TLS协议对传输的数据进行加密,以保证传输过程当中的安全性,因此https协议=SSL/TLS+http协议
。java
通常对于信息安全问题,主要须要解决三大问题:身份明确性,数据保密性,数据完整性,所以,https针对这三个问题的解决方法是(1)使用数字证书识别身份;(2)使用加密技术(对称加密和非对称加密)保证数据保密性;(3)使用数据签名防止数据被篡改;具体这里涉及到对称加密,非对称加密,数字签名,数字证书及SSL/TLS的运行原理等概念,此处不详细展开,能够参考文章《一文看懂HTTPS、证书机构(CA)、证书、数字签名、私钥、公钥》和《SSL/TLS协议运行机制的概述》。linux
刚才已经说到,https是使用数字证书来识别身份,即肯定当前访问的服务器是真的。数字证书由权威的颁发机构(CA)在验证服务器身份后颁发的一种数字证书,内容包含加密后服务器的公钥、权威机构的信息、有效期,证书内容的数字签名(经过Hash函数计算获得证书数字摘要,而后用权威机构私钥加密数字摘要获得数字签名),签名计算方法以及证书对应的域名。最重要的是服务器的公钥,另外,这里所说的CA能够是商用的,也能够自建来私有使用(只是自建的CA生成的证书浏览器不公认)。spring
公钥、私钥是非对称加密中的概念:公钥(public key)是对外开放的,私钥(private key)是本身拥有的。公钥加密的数据,只能用私钥解密。私钥加密的数据,只能用公钥解密。chrome
数字证书是使用数字签名来识别身份。当客户端收到服务器的证书以后,使用CA的公钥对证书自己进行解密获得服务端的公钥和证书的数字签名,数字签名通过CA公钥解密获得证书信息摘要。而后证书签名的方法计算一下当前证书的信息摘要,与收到的信息摘要做对比,若是同样,表示证书必定是服务器下发的,没有被中间人篡改过。详细可参见《数字证书基本知识总结》、《Java 和 HTTP 的那些事(四) HTTPS 和 证书》、《一次看懂 Https 证书认证》shell
前面使用到的证书从使用者来看,分别有CA证书,服务端(server)证书和客户端(client)证书。其中,CA证书做为根证书,由它来签发server证书和client证书,也由它的公钥和私钥对server证书和client证书进行识别。server证书的公钥和私钥用于https通讯过程数据加解密等操做。通常对于服务器的单向认证,只须要CA证书和服务端证书。apache
按证书格式分,X.509#DER二进制格式证书,经常使用后缀.cer .crt;X.509#PEM文本格式证书,经常使用后缀.pem;有的证书内容是只包含公钥(服务器的公钥),如.crt、.cer、.pem;有的证书既包含公钥又包含私钥(服务器的私钥),如.pfx、.p12后端
openssl 是一套密码库工具,用以支持SSL/TLS 协议的实现,能够用它生成证书,进行数据加解密,计算消息摘要等等。经过它能够进行自签名证书(把本身看成CA机构),实现https访问。本文使用的就是这种方式。通常linux已自带安装,没有安装的须要下载安装。浏览器
keytool是一个Java数据证书的管理工具 ,位置是在java安装目录下的bin目录。keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中。 注意keystore不只能够存储数字证书,还能够存储密钥。存储在 Keystore 文件中的对象有三种类型:Certificate、PrivateKey 和 SecretKey 。Certificate 就是证书,PrivateKey 是非对称加密中的私钥,SecretKey 用于对称加密,是对称加密中的密钥。所以,对于java应用中,能够直接使用keytool便可生成相应的keystore进行https设置。
了解了基本概念后,如今开始动手进行https部署。第一步是先进行自签证书,这里使用openssl生成证书,而后使用keytool生成相应的keystore文件。
如下命令操做在linux下完成,作的是服务端单向认证
# 生成根证书私钥
openssl genrsa -des3 -passout pass:111111 -out ca.key 2048
# 签发根证书
openssl req -new -x509 -days 3650 -passin pass:111111 -key ca.key -out ca.crt -subj "/C=CN/ST=GD/L=GZ/O=test/OU=test/CN=${ip或域名}"
复制代码
说明,上述操做中:
pass:111111
表示ca证书的密码,能够自定义,这样能够避免以交互方式输入密码,密码能够自定义。-subj
中,CN为根证书的域名,请根据实际状况填写。days
能够随便填数量。# 生成服务器证书私钥
openssl genrsa -des3 -passout pass:111111 -out server.key 2048
# 生成服务器证书请求
openssl req -new \
-sha256 \
-key server.key \
-passin pass:111111 \
-subj "/C=CN/ST=GD/L=GZ/O=test/OU=test/CN=${ip或域名}" \
-reqexts SAN \
-config <(cat /path/to/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=IP:${ip或域名}")) \
-out server.csr
# 签发服务器证书
openssl ca -in server.csr \
-days 3650 \
-passin pass:111111 \
-md sha256 \
-keyfile ca.key \
-cert ca.crt \
-extensions SAN \
-config <(cat /path/to/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=IP:${ip或域名}")) \
-out server.crt
复制代码
说明,上述操做中:
-subj
中,CN为根证书的域名,请根据实际状况填写。/path/to/openssl.cnf
,请根据实际的openssl.cnf位置修改。[SAN]\nsubjectAltName
,若使用IP,则以IP:
开头,如果域名,使用DNS:
开头。# 生成服务器证书转pkcs12
openssl pkcs12 -export -in server.crt -passin pass:111111 -passout pass:111111 -inkey server.key -out server.pkcs12
# pkcs12转keystore
keytool -importkeystore -v -srckeystore server.pkcs12 -srcstoretype pkcs12 -srcstorepass 111111 -destkeystore server.jks -deststoretype jks -deststorepass 111111 -noprompt
复制代码
至此,咱们已经生成了后面须要使用到的ca.crt
,server.key
,server.crt
,server.jks
。
因为Chrome 58 及以上版本只会使用 subjectAlternativeName 扩展程序(而不是 CN即commonName)来匹配域名和网站证书。所以,在生成证书时须要加上SAN。参考文章《OpenSSL 生成「自签名」证书遇到的 missing_subjectAltName 问题》及《使用 OpenSSL 制做一个包含 SAN(Subject Alternative Name)的证书》
遇到相似“/etc/pki/CA: No such file or directory”错误,解决方法是在当前目录(若是是默认安装的openssl,在/etc/pki/CA)执行下面命令:
mkdir -p /etc/pki/CA
cd /etc/pki/CA
touch index.txt
touch serial
echo 01 > serial
复制代码
java工程使用keystore进行证书管理,先把server.jks放到springboot工程的resource目录下。而后在springboot配置文件application.properties添加如下配置:
# https访问端口
server.port=443
server.ssl.key-store=server.jks
server.ssl.key-alias=server
server.ssl.enabled=true
server.ssl.key-store-password=111111
server.ssl.key-store-type=JKS
复制代码
若是是使用tomcat部署,其实直接在tomcat的配置文件中进行配置https的connector便可。对于springboot,通常咱们经过添加配置文件,以实现对tomcat的配置修改。新建TomcatConfig.java文件,添加如下代码:
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(Connector connector) {
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(connector);
return tomcat;
}
@Bean
public Connector connector(){
Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//http端口
connector.setPort(8080);
connector.setSecure(false);
// https端口,即server.port
connector.setRedirectPort(serverPort);
return connector;
}
复制代码
说明,此处新建了http的Connector,并把http的访问都转发到https,这样,当用户访问http时直接跳转为https。若须要http和https同时使用,则把setRedirectPort
去掉便可。
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
复制代码
使用Include引入ssl配置,以下:
Include conf/extra/httpd-ssl.conf
复制代码
把容许重写设置为All,把AllowOverride None 改成 AllowOverride all
<Directory "/root/path/">
Options Indexes FollowSymLinks
AllowOverride all
Require all granted
</Directory>
复制代码
前端已经引入httpd-ssl.conf文件,所以,须要对此文件进行ssl配置。以下:
# 启用https端口
Listen 443 https
# 启用SSL并设置服务端证书及私钥
SSLEngine on
SSLCertificateFile "/path/to/server.crt"
SSLCertificateKeyFile "/path/to/server.key"
复制代码
说明:根据实际状况设置证书路径。
在网站目录下建立一个.htaccess
文件,写入以下规则,把所有80端口的请求都转发到本机的https对应的端口(默认443):
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]
复制代码
前端须要调用后端接口,因为已经改成使用https通讯,所以,调用接口须要从原来http地址,改成https访问的端口。上述所有配置完成后,重启apache便可(重启须要输入server.key对应的密码)
最后,因为使用的是自签名的证书,浏览器不认识这证书,所以,须要把自签的CA证书添加到浏览器中,才能正常访问。以chrome浏览器为例,设置-》高级》隐私设置和安全性》管理证书》受信息的根证书颁发机构,导入ca.crt。这样,就能够愉快地使用https,不提示安全问题了。
本文经过操做实例进行了对springboot+apache先后端分离项目的https部署,先对https、证书、openssl及keytool进行初步的了解,而后经过openssl和keytool生成证书及keystore,接着对后端springboot及前端的apache分别进行配置。但愿能够帮助到一样须要进行https部署的同窗。
关注个人公众号(搜索Mason技术记录
),获取更多技术记录: