目录
一、Spring boot部署SSL证书
1、申请并下载SSL证书
我是阿里云的服务器,阿里云有免费的SSL证书可以申请,申请后下载Tomcat类别对应的证书。解压后获得.pfx
文件和.txt
文件,.txt
内存放的是证书密码。
注意:不要下载jks格式的证书,原因后面会讲到
2、生成.jks文件
在命令行界面进入jdk安装目录,我的是C:\Program Files (x86)\Java\jdk1.8.0_192\bin
,后续工作都在这个目录中进行。
cd C:\"Program Files (x86)"\Java\jdk1.8.0_192\bin
# 不加引号会报错:
# x86 : 无法将“x86”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
生成.jks
文件
keytool -importkeystore -srckeystore pfx文件 -destkeystore 生成的.jks文件 -srcstoretype PKCS12 -deststoretype JKS
# 建议两个文件目录和名称用绝对路径表示,如:C:\Users\xxx\Desktop\cert.pfx C:\Users\xxx\Desktop\cert.jks
生成时会让输入密码,也就是第一步.txt
文件中的证书密码,然后需要输入.jks
文件的密码,可以自己设定,不过建议使用和.pfx
证书一样的密码。这里的密码输入和Ubuntu输sudo密码一样是隐式输入,输入并不显示输入信息,确认输完了回车就完事,如果是一样的密码就可以直接粘贴-回车三次,方便快捷(不是)。
完成后会显示已成功导入别名为 alias 的项目
,记住这里的别名。
这个别名也正是花了了我半个多小时的怪坑
3、在项目中部署
将生成的.jks
文件复制到application.properties
的同级目录,然后在application.properties
中进行相关配置:
#端口号 根据项目需求配置 默认https端口号是443 如果同时部署了nginx的SSL也使用了443端口就需要换个端口
server.port=443
#SSL证书路径
server.ssl.key-store=classpath:myssl.jks
#SSL证书密码
server.ssl.key-store-password=前面设置的jks证书密码
#证书类型
server.ssl.key-store-type=JKS
#证书别名 前面的别名
server.ssl.key-alias=alias
4、修改启动类,让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.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class WebchatApplication {
public static void main(String[] args) {
SpringApplication.run(WebchatApplication.class, args);
}
/**
* http重定向到https
* @return
*/
@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");
connector.setScheme("http");
// Connector监听的http的端口号
connector.setPort(8080);
connector.setSecure(false);
// 重定向的https的端口号,和前面application.properties中的设置需要一致
connector.setRedirectPort(443);
return connector;
}
}
二、keytool相关
1、keytool
keytool 是一个Java 数据证书的管理工具,keytool 将密钥(key)和证书(certificates)存在一个称为keystore的文件中 在keystore里,包含两种数据:
- 密钥实体(Key entity):密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)
- 可信任的证书实体(trusted certificate entries):只包含公钥
每个keystore都关联这一个独一无二的alias(别名),通常不区分大小写
2、keytool 常用命令
-genkey
:在用户主目录中创建一个默认文件.keystore
,还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书。在没有指定生成位置的情况下,keystore会存在用户系统默认目录(不建议)。
-alias
:产生指定别名
-keystore
指定密钥库的名称(产生的各类信息将不在.keystore文件中)
-keyalg
:指定密钥的算法(如:RSA,DSA,如果不指定默认采用DSA)
-validity
:指定创建的证书有效期多少天
-keysize
:指定密钥长度
-storepass
:指定密钥库的密码(获取keystore信息所需的密码)
-keypass
:指定别名条目的密码(私钥的密码)
-dname
:指定证书拥有者信息,例如:“CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码”
-list
:显示密钥库中的证书信息
-v
:显示密钥库中的证书详细信息,keytool -list -v -keystore jks文件
-export
:将别名指定的证书导出到文件
-file
:参数指定导出到文件的文件名
-delete
:删除密钥库中某条目,如:keytool -delete -alias 需删除的别名 -keystore 秘钥库名称 -storepass 密码
-printcert
:查看导出的证书信息
-keypasswd
:修改密钥库中指定条目口令,如:keytool -keypasswd -alias 需修改的别名 -keypass 旧密码 -new 新密码 -storepass keystore 密码 -keystore 名称
-storepasswd
:修改keystore口令,如keytool -storepasswd -keystore e:/yushan.keystore(需修改口令的keystore) -storepass 123456(原始密码) -new yushan(新密码)
-import
:将已签名数字证书导入密钥库,如:keytool -import -alias 指定导入条目的别名 -keystore 指定keystore -file 需导入的证书
下面是各选项的缺省值:
-alias
mykey(我在使用时是alias)
-keyalg
DSA
-keysize
1024
-validity
90
-keystore
用户宿主目录中名为 .keystore 的文件
-file
读时为标准输入,写时为标准输出
3、遇到的坑
(1)为什么不要下载阿里云jks格式的证书
太长不看版:阿里云的jks秘钥库中有2个分别名为alias-key
、alias-cert
的条目,自己生成的jks秘钥库中只有1个名为alias
的条目,阿里云的jks秘钥库无法直接使用alias别名在application.properties文件中进行配置。
详情如下:使用keytool -list -v -keystore jks文件名
分别查看自己生成的jks文件和阿里云下载的jks文件区别。
- 首先是阿里云下载的jks文件
密钥库类型:jks
密钥库提供程序:IBMJCE
您的密钥库包含 2 个条目
别名:alias-key
创建日期:2020-xx-xx
条目类型:keyEntry
证书链长度:2
证书[1]:
所有者:CN=xxxxxx.top
颁发者:CN=Encryption Everywhere DV TLS CA - G1, OU=www.digicert.com, O=DigiCert Inc, C=US
序列号:xxxxxxx
有效期自:20-xx-xx 上午8:00 至:21-xx-xx 上午7:59
证书指纹:
MD5:xxxx
SHA1:xxxx
SHA256:xxxx
签名算法名称:xxxx
版本:3
扩展:(省略)
证书[2]:
所有者:CN=Encryption Everywhere DV TLS CA - G1, OU=www.digicert.com, O=DigiCert Inc, C=US
颁发者:CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
序列号:xxxxxxxxxx
有效期自:xx-xx-xx 下午8:xx 至:xx-xx-xx下午8:xx
证书指纹:
MD5:xxxx
SHA1:xxxx
SHA256:xxxx
签名算法名称:xxxx
版本:3
扩展:
(省略)
*******************************************
*******************************************
别名:alias-cert
创建日期:2020-xx-xx
条目类型:trustedCertEntry
所有者:CN=xxxxxx.top
颁发者:CN=Encryption Everywhere DV TLS CA - G1, OU=www.digicert.com, O=DigiCert Inc, C=US
序列号:xxxxxxx
有效期自:20-xx-xx 上午8:00 至:21-xx-xx 上午7:59
证书指纹:
MD5:xxxx
SHA1:xxxx
SHA256:xxxx
签名算法名称:xxxx
版本:3
扩展:(省略)
*******************************************
- 然后是我自己生成的jks文件
密钥库类型:jks
密钥库提供程序:IBMJCE
您的密钥库包含 1 个条目
别名:alias
创建日期:2020-10-19
条目类型:keyEntry
证书链长度:2
证书[1]:
所有者:CN=xxxxxxxx.top
颁发者:CN=Encryption Everywhere DV TLS CA - G1, OU=www.digicert.com, O=DigiCert Inc, C=US
序列号:xxxxxxx
有效期自:20-xx-xx 上午8:00 至:21-xx-xx 上午7:59
证书指纹:
MD5:xxxx
SHA1:xxxx
SHA256:xxxx
签名算法名称:xxxx
版本:3
扩展:(省略)
证书[2]:
所有者:CN=Encryption Everywhere DV TLS CA - G1, OU=www.digicert.com, O=DigiCert Inc, C=US
颁发者:CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
序列号:xxxx
有效期自:17-11-27 下午8:46 至:27-11-27 下午8:46
证书指纹:
MD5:xxxx
SHA1:xxxx
SHA256:xxxx
签名算法名称:xxxx
版本:3
扩展:(省略)
*******************************************
(2)Tomcat启动报错当前端口已被占用(实际没有被占用)
太长不看版:如果使用http部署完全正常,很有可能是别名、证书密码、证书路径配置出错。 任意一个配置出错Spring boot均有可能在启动时报“tomcat当前端口已经被占用”的错误。
-
有关别名:不同jdk提供的keytool缺省别名可能不一样,所以生成文件时建议使用
-alias
进行配置,或者生成之后使用keytool -list -v -keystore jks文件名
查看别名,使用正确的别名进行配置。 -
有关证书密码:记住自己设置的密码,
application.properties
中配置的密码是生成的jks文件密码,与pfx文件密码无关,为了避免这个问题,建议使用相同密码。 -
有关证书路径配置:jks证书建议放在
application.properties
同目录下,这样就可以直接classpath:jks文件名
进行配置,否则容易路径配置出错。