1. SSL证书简介
一般来说,主流的Web服务软件,通常都基于两种基础密码库:OpenSSL和Java。Tomcat、Weblogic、JBoss等,使用Java提供的密码库。通过Java的Keytool工具,生成Java Keystore(JKS)格式的证书文件。Apache、Nginx等,使用OpenSSL提供的密码库,生成PEM、KEY、CRT等格式的证书文件。另外,PFX(PKCS12)主要应用于IIS,KDB主要应用于IHS和Websphere。各类证书的关系如下图所示:<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/788484/1600304999147-9a225310-44ed-40d6-8b67-ab7004712b8a.png#height=192&id=EztfB&margin=%5Bobject%20Object%5D&name=image.png&originHeight=384&originWidth=962&originalType=binary&ratio=1&size=149525&status=done&style=none&width=481)
2. HTTPS配置步骤
- 申请SSL证书(先决条件:拥有域名,可在腾讯云、阿里云上免费申请,或者使用自签证书)。
- 如有需要将证书转换为对应Web服务器版本,如Tomcat需要jks证书。
- SpringBoot工程添加SSL证书及证书配置。
3. SSL证书申请
1. CA颁发证书
略,请查阅相关参考。2. 自签署证书
用JDK/JRE自带的keytool工具来生成SSL证书。常用参数如下所示:
- alias:证书别名。
- storetype:指定密钥仓库类型,不指定则JDK会默认选用JKS,其他常用还有PKCS12,内置Tomcat只支持PFX(PKCS12)或__JKS。
- keyalg:生证书的算法名称,RSA是一种非对称加密算法。
- keysize:证书大小。
- keystore:生成的证书文件的存储路径。
- validity:证书的有效期。
生成证书:
@rem 进入%JAVA_HOME%/bin目录,如果配置了%PATH%则任意目录下都可以运行以下命令
D:
cd D:\jdk\jdk8x64\bin
# 交互式安装
keytool -genkey -alias tomcat -keyalg RSA -keysize 2048 -keystore E:\tmp\dev.polaris.com.jks -validity 3650
# -----交互输入-----
输入密钥库口令: [V1OUC2e0]
再次输入新口令: [V1OUC2e0]
您的名字与姓氏是什么?
[Unknown]: [wj]
您的组织单位名称是什么?
[Unknown]: [dev.polaris.com]
您的组织名称是什么?
[Unknown]: [polaris Inc]
您所在的城市或区域名称是什么?
[Unknown]: [sz]
您所在的省/市/自治区名称是什么?
[Unknown]: [gd]
该单位的双字母国家/地区代码是什么?
[Unknown]: [cn]
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
[否]: 是
# 静默式安装
keytool -genkeypair -alias tomcat -keypass V1OUC2e0 -storepass V1OUC2e0 -dname "C=CN,ST=GD,L=SZ,O=wj,OU=dev,CN=polaris.com" -keyalg RSA -keysize 2048 -validity 3650 -keystore E:\tmp\dev.polaris.com.jks
查看证书:
@rem 查看生成证书
keytool -list -v -storetype JKS -keystore E:\tmp\dev.polaris.com.jks
@rem 也可以将结果输出到文件
keytool -list -v -storetype JKS -keystore E:\tmp\dev.polaris.com.jks > out.log
4. SSL证书转换
根据Web服务器需求(见第1章节),将证书转换为其支持的类型。
@rem 进入%JAVA_HOME%/bin目录,如果配置了%PATH%则任意目录下都可以运行以下命令
D:
cd D:\jdk\jdk8x64\bin
# 示例1:将PFX转换为JKS证书
keytool -importkeystore -srckeystore E:\tmp\dev.polaris.com.pfx -destkeystore E:\tmp\dev.polaris.com.jks -srcstoretype PKCS12 -deststoretype JKS
# 示例2:将JKS转换为PFX证书
keytool -importkeystore -srckeystore E:\tmp\dev.polaris.com.jks -destkeystore E:\tmp\dev.polaris.com.pfx -srcstoretype JKS -deststoretype PKCS12
keytool -importkeystore -deststorepass V1OUC2e0 -destkeypass V1OUC2e0 -srckeystore E:\tmp\dev.polaris.com.jks -destkeystore E:\tmp\dev.polaris.com.pfx -srcstoretype JKS -deststoretype PKCS12 -srcstorepass V1OUC2e0
5. SSL证书配置Web站点
1. Tomcat & SSL
Ø 场景1:Tomcat-7.0.103(Http11Protocol)
<?xml version='1.0' encoding='utf-8'?>
<Server port="18005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="18080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
<Connector port="8444" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="conf/local.polaris.org.jks"
keystorePass="V1OUC2e0" />
<Connector port="18009" protocol="AJP/1.3" redirectPort="8444" secretRequired=""/>
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
Ø 场景2:Tomcat-8.5.5(Http11Nio2Protocol)
server.xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="18080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
<Connector port="8444"
protocol="org.apache.coyote.http11.Http11Nio2Protocol" maxThreads="150" SSLEnabled="true" >
<SSLHostConfig >
<Certificate certificateKeystoreFile="conf/local.polaris.org.jks"
certificateKeystorePassword="V1OUC2e0"
type="RSA" />
</SSLHostConfig>
</Connector>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8444" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
web.xml ```xml <?xml version=”1.0” encoding=”UTF-8”?>
<web-resource-collection>
<web-resource-name>OPENSSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
<session-timeout>30</session-timeout>
<cookie-config>
<secure>true</secure>
</cookie-config>
<a name="zSv96"></a>
### Ø 场景3:Tomcat-9.0.37(TLSv1.2)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
name="UserDatabase"
pathname="conf/tomcat-users.xml"
type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"/>
<Connector port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
acceptCount="100"
maxThreads="150"
SSLEnabled="true"
allowTrace="false"
xpowereBy="false"
secure="true">
<SSLHostConfig protocol="TLSv1.2"
ciphers="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA">
<Certificate certificateKeystoreFile="/data/cert/HTTPS_UAT/keystore"
certificateKeystorePassword="P@s;w;0;r;d"
type="RSA" />
</SSLHostConfig>
</Connector>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
pattern="%h %l %u %t "%r" %s %b"
prefix="localhost_access_log"
suffix=".txt"/>
<Valve className="org.apache.catalina.valves.ErrorReportValue"
showReport="false"
showServerInfo="false" />
</Host>
</Engine>
</Service>
</Server>
2. SpringBoot & SSL
Ø SpringBoot配置SSL
将证书复制到项目根目录(如:resources),修改application.properties 或 application.yml。
# https请求访问端口,https默认443端口,配置后可以不带端口访问站点
server.port=443
# 开启https
server.ssl.enabled=true
# 密钥仓库路径
server.ssl.key-store=classpath:dev.polaris.com.jks
# 签名密码
server.ssl.key-store-password=V1OUC2e0
# 密钥仓库类型
server.ssl.keyStoreType=JKS
# 别名,根据证书情况配置,如果证书没有,则无需配置
server.ssl.keyAlias=tomcat
# 指定Spring Security请求也需要透过HTTPS签名文件
# security.require-ssl=true
以上配置完成之后我们就可以通过HTTPS来访问我们的Web了。
Ø HTTP自动转向HTTPS
在安装网站证书后我们需要将所有http的请求自动跳转到https,这样才能让整站证书生效。
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.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SSLConfig {
@Bean
public Connector connector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(443);
return connector;
}
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
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;
}
}
Ø SpringBoot跨域配置
WebMvcConfigurer对象配置跨域:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
.maxAge(3600);
}
};
}
3. Nginx & SpringBoot & SSL
此种模式下,SpringBoot不需要做相关配置,仅需要配置Nginx即可。
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# HTTPS server
server {
listen 443 ssl;
server_name dev.polaris.com;
ssl on;
ssl_certificate /usr/local/nginx/key/dev.polaris.com.pem;
ssl_certificate_key /usr/local/nginx/key/dev.polaris.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!3DES:!aNULL:!eNULL;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://192.168.0.103:9080;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
#proxy_cookie_path
chunked_transfer_encoding off;
}
}
}
4. Apache & SSL
安装ssl模块。
# 查看是否已安装ssl模块
ls /etc/httpd/modules |grep mod_ssl
# 安装ssl模块
yum -y install mod_ssl openssl
生成并上传证书。
mkdir -p /etc/httpd/cert/CA
生成私钥
(umask 077; openssl genrsa -out /etc/httpd/cert/CA/cakey.pem 4096)
生成自签证书
openssl req -new -x509 -key /etc/httpd/cert/CA/cakey.pem -out /etc/httpd/cert/CA/cacert.pem -days 3655
# -----交互输入-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:dev.polaris.com
Organizational Unit Name (eg, section) []:polaris
Common Name (eg, your name or your server's hostname) []:dev.polaris.com
Email Address []:dev@polaris.com
CA初始化
touch /etc/httpd/cert/CA/{serial,index.txt}
echo 01 > /etc/httpd/cert/CA/serial
- 测试站点准备。
主机名配置
vi /etc/hosts
内容如下:
192.168.0.103 dev.polaris.com
模拟网站及内容
mkdir -p /home/wwwroot/dev
echo "dev.polaris.com" > /home/wwwroot/dev/index.html
- SSL配置。
内容如下: ```xmlmkdir -p /etc/httpd/conf/extra
vi /etc/httpd/conf/extra/httpd-ssl.conf
非默认端口(443),需要配置此处监听端口
Listen 9443
5. 主配置文件更新。
```bash
vi /etc/httpd/conf/httpd.conf
内容如下:
LoadModule ssl_module modules/mod_ssl.so
Include /etc/httpd/conf/extra/httpd-ssl.conf
重启生效配置。
systemctl restart httpd
验证。
curl https://dev.polaris.com:9443
补充(设置HTTP请求自动跳转HTTPS):
# 在httpd.conf文件中的<VirtualHost *:80> </VirtualHost>中间,添加以下重定向代码
RewriteEngine on
RewriteCond %{SERVER_PORT} !^9443$
# 以下配置如果端口为443,则可以省略“:9443”
RewriteRule ^(.*)$ https://%{SERVER_NAME}:9443$1 [L,R]
5. IHS & SSL
IHS版本为:9.0.5.7。
创建目录
mkdir -p /opt/IBM/HTTPServer/ssl/
进入IHS命令执行目录
cd /opt/IBM/HTTPServer/bin
创建CMS密钥库
./gskcapicmd -keydb -create -db /opt/IBM/HTTPServer/ssl/key.kdb -pw pWd33mypa -type cms -expire 3650 -stash
填充自签证书
./gskcapicmd -cert -create -db /opt/IBM/HTTPServer/ssl/key.kdb -pw pWd33mypa -dn "cn=polaris.org" -label "myssl" -size 2048 -default_cert yes
查看证书
# 查看CA证书
./gskcapicmd -cert -list ca -db /opt/IBM/HTTPServer/ssl/key.kdb -pw pWd33mypa -type cms
# 查看所有证书
./gskcapicmd -cert -list all -db /opt/IBM/HTTPServer/ssl/key.kdb -pw pWd33mypa -type cms
重置证书
./gskcapicmd -keydb /opt/IBM/HTTPServer/ssl/key.kdb -stashpw -pw pWd33mypa -db /opt/IBM/HTTPServer/ssl/key.kdb
IHS配置
vi /opt/IBM/HTTPServer/conf/httpd.conf
内容如下:
# SSL Config Begin
LoadModule ibm_ssl_module modules/mod_ibm_ssl.so
<IfModule mod_ibm_ssl.c>
Listen 443
<VirtualHost *:443>
SSLEnable
</VirtualHost>
</IfModule>
SSLDisable
KeyFile "/opt/IBM/HTTPServer/ssl/key.kdb"
# SSL Config End
IHS操作
cd /opt/IBM/HTTPServer/bin
# 启动Web服务器
./apachectl start
# 停止Web服务器
./apachectl stop
# 重启Web服务器
./apachectl restart
追踪IHS错误日志
tail -f -n200 /opt/IBM/HTTPServer/logs/error_log
参考
博客园:主流数字证书都有哪些格式
https://www.cnblogs.com/lhj588/p/6069873.html
博客园:SpringBoot2.x配置Cors跨域
https://www.cnblogs.com/anxminise/p/9808279.html
简书:HTTPS之自签名证书配置
https://www.jianshu.com/p/01c4f7a7b2c5
简书:搭建Apache并使用自签证书实现https访问
https://www.jianshu.com/p/771b5a243215
IBM:IBM HTTP Server 证书管理
https://www.ibm.com/docs/zh/was-nd/9.0.5?topic=SSAW57_9.0.5/com.ibm.websphere.ihs.doc/ihs/cihs_certmgmt.html
CA颁发证书参考
CSDN:SpringBoot2.0配置https访问
https://blog.csdn.net/qq_40715775/article/details/82780881
B站:SSL认证视频参考-阿里云SSL证书上/中/下
https://www.bilibili.com/video/av53590261?from=search&seid=14115886556208614240
B站:SSL认证视频参考-腾讯云免费SSL证书配置
https://www.bilibili.com/video/av43700323?from=search&seid=9870719472163478832
B站:数字签名及数字证书原理
https://www.bilibili.com/video/BV18N411X7ty
B站:240分钟搞懂HTTP和HTTPS协议
https://www.bilibili.com/video/BV1F54y1t7Dx
阿里云:在Apache服务器上安装SSL证书
https://www.alibabacloud.com/help/zh/doc-detail/98727.htm