SpringBoot 配置 Tomcat SSL
SpringBoot 配置 Tomcat SSL
SSL(Secure Sockets Layer , 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通信提供安全支持。SSL协议可分为两层:SSL记录协议(SSL Record Protocol),它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议(SSL Handshake Protocol),它建立在SSL记录协议之上,用于在实际数据传输开始前,通信双方进行身份认知、协商加密算法、交换加密密钥等。而在基于B/S的Web应用中,是通过HTTPS来实现SSL的。HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即在HTTP下加入SSL层,HTTPS的安全基础是SSL。因为SpringBoot用的是内嵌的Tomcat,因而我们做SSL配置的时候需要做如下的操作。
1.生成证书
使用SSL首先需要一个证书,这个证书既可以是自签名的,也可以是从SSL证书授权中心获得的。
在JRE安装bin目录内shift+右键打开CMD窗口,输入如下命令:
keytool -genkey -alias tomcat -keyalg RSA
此时在当前用户目录下(默认C:\Users\Administrator)会生成.keystore证书文件 ,将这个文件拷贝到SpringBoot项目Classpath根目录下
2.application.properties中配置SSL
#SSL server.port: 8443 server.ssl.key-store: classpath:.keystore server.ssl.key-store-password: xianlei server.ssl.keyStoreType: JKS server.ssl.keyAlias: boottomcat server.tomcat.max-threads: 100 server.tomcat.min-spare-threads: 20 server.connection-timout: 5000
3.配置HTTP转向HTTPS
package com.xianlei.springBoot; 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.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringBootThymeleafApp { public static void main(String[] args) { SpringApplication.run(SpringBootThymeleafApp.class, args); } @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(8091);//配置任意默认端口 connector.setSecure(false); connector.setRedirectPort(8443);//https重定向端口 return connector; } }
4.启动SpringBoot, 控制台输出效果如下
可以看到,SpringBoot启动了两个端口的监听,http 端口的8091 和 https端口的8443。
5.访问http://localhost:8091/, 会自动转向至http://localhost:8443/
由于是自签名的证书,所以是不安全的。正式环境不推荐直接这样使用。
推荐从在网上证书授权中心如阿里云、腾讯云等购买SSL证书。
附:
查看密钥库,已存在的证书列表命令:
keytool -list-v
导出证书
Keytool -exportcert -alias tomcat -file c:\tomcat.cer
1. 导入
最近在开发中,笔者遇到了这样的问题:当第三方向我们系统请求pay bill业务时,我们的系统就会报错,而且错误的信息是找不到有效的证书,所以交易就被cancelled了。我们不去深究为什么会有这样的错误,笔者今天主要讲的是关于keytool的相关知识,因为了解这个,你就会知道上面的问题是为什么了。
2. keytool介绍
笔者查找了关于keytool的相关解释,网站上给出的定义是:keytool 是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。它还允许用户储存他们的通信对等者的公钥(以证书形式)。其实笔者个人的理解就是,当外面系统要访问我们的系统的时候,就需要给出双方彼此信任的证书,证书里面就包含了外部系统的个人信息,例如:公司名称、公司地址、密码等。而Keytool把钥匙和证书储存到一个keystore,默任实现keystore的是一个文件.它用一个密码保护钥匙.。只有这些信息对应上了,我们的系统才可放行,让外部系统进入到我们的系统内,并进行相关的业务操作。这种情况我们更多见的是在一些支付系统、银行系统中。如图所示:
3. keytool之数据证书
关于keytool相信java开发的程序员并不会陌生,在JDK\Bin的目录下你就可以看到keytool.exe的执行文件,不过不能双击执行。而我们通过dos的命令来创建数字证书,主要就是用keytool.exe的程序了。所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的数字证书的信息。证书库中的一条证书可以导出数字证书文件,数字证书文件只包括主体信息和对应的公钥。
4. 证书的概念
一个证书是一个实体的数字签名,还包含这个实体的公共钥匙值.
1) 公共钥匙 :是一个详细的实体的数字关联,并有意让所有想同这个实体发生信任关系的其他实体知道.公共钥匙用来检验签名;
2) 数字签名:是实体信息用实体的私有钥匙签名(加密)后的数据.这条数据可以用这个实体的公共钥匙来检验签名(解密)出实体信息以鉴别实体的身份;
3) 签名:用实体私有钥匙加密某些消息,从而得到加密数据;
4) 私有钥匙:是一些数字,私有和公共钥匙存在所有用公共钥匙加密的系统的钥匙对中.公共钥匙用来加密数据,私有钥匙用来计算签名.公钥加密的消息只能用私钥解密,私钥签名的消息只能用公钥检验签名。
5) 实体:一个实体可以是一个人,一个组织,一个程序,一台计算机,一个商业,一个银行,或其他你想信任的东西.
5. keytool的基本用法
在开始学习keytool的用法,要清楚的是,keytool把钥匙和证书储存到一个keystore。而默认的keystore就是一个文件,它用一个密码保护钥匙。所有的keystore入口(钥匙和信任书入口)是通过唯一的别名。别名是不区分大小写的。例如别名Owen和owen指向同一个keystore入口。为此,我们可以用-import参数加一个证书或证书链到信任证书。
1) 产生一个新的公/私有钥匙对。
语句:keytool -genkey -alias owen -keypass owenkeypasswd
解释:其中owen为别名,owenkeypasswd为owen别名的密码。
2) 修改owen别名的密码。
语句:keytool-keypasswd -alias owen -keypass owenkeypasswd -new newpass
解释:使用-new将旧密码owenkeypasswd改为newpass
3) 检查一个keystore。
语句:keytool -list -v-keystore owen
Enter keystore password:your password(输入密码)
解释:使用-list来查找已经创建好的keystore,在查询中还要输入密码
4) 输出keystore到一个文件。
语句:keytool -export-alias owen -keystore keystore -rfc -file owenkey
系统输出:
Enter keystore password:your password(输入密码)
Certificate stored in file
解释:这可能有点不好解理,我们来看一个具体的例子:
keytool -export -keystore monitor.keystore-alias monitor -file monitor.cer
上面的这句话就是把证书库monitor.keystore中别名为monitor的证书导出到monitor.cer证书中。它包含证书主体的信息及证书的公钥,不包括私钥,可以公开。
5) 输入证书到一个新的truststore
语句:keytool -import -alias dukecert -filetestkey -keystore truststore
Enter keystore password:your new password.(输入truststore新密码)
解释:例如我们要将keystore导入证书中,这里向Java默认的证书cacerts导入Rapa.cert。我们可以这样写:
keytool -import -alias RapaServer -keystorecacerts -file Rapa.cert -keystore cacerts
6) 证书条目的删除
语句:keytool -delete-alias RapaServer -keystore d2aApplet.keystore
解释:将d2aApplet.keystore中的RapaServer这一条证书删除
7) 将证书导出到证书文件
语句:keytool -export -alias myCA -file myCA.cer-keystore myCALib -storepass 123456 –rfc
解释:使用命令从名为myCALib的keystore中,把别名为myCA的证书导出到证书myCA.cer中。其中,-storepass指定keystore的密码,-rfc指定可以查看编码的方式输出,可省略。
8) 通过证书文件查看证书信息
语句:keytool-printcert -file myCA.cer
解释:输入上面的信息将会看到myCA.cer证书的信息
9) 密钥库中证书条目口令的修改
语句:Keytool -keypasswd -alias myCA -keypass654321 -new newpass -storepass 123456 -keystore myCALib
10) 删除密钥库中的证书条目
语句:keytool -delete-alias myCA -keystore myCALib
11) 把一个证书文件导入到指定的密钥库
语句:keytool -import-alias myCA -file myCA.cer -keystore truststore
解释:将myCA.cer证书文件导入到truststore 密钥库中,如果没有名为truststore ,将自动创建,并会提示输入keystore的密码。
12) 更改密钥库的密码
语句:keytool -storepasswd -new 123456 -storepass 789012 -keystore truststore
解释:其中-storepass指定原密码,-new指定新密码
6. keytool实例
在开始实战keytool的用法之前,笔者希望读者可自己创建个文件夹来操作。笔者在E盘下创建了keytool的文件夹,并将目录切换到此文件夹下。同时,我们的操作的一般格式是:
keytool + 操作类型[-genkey,-list-v,-printcert -file,-import -flie,-export -file,-delete,-
keypasswd -new,-storepasswd -new] + 再加上上面的格式.
1) 生成一个别名为myStore的自签名证书,证书的keypair的密码为123456.证书信息为”CN=owen,OU=chinasoft,O=cps,L=sz,ST=gd,C=china”,将证书存储在名为myService.keystore的keystore中(如果没有将自动生成一个),这个keystore的密码为654321.密钥对生产的算法指定为RSA,有交期为10年。执行命令如下:
keytool -genkey -alias myStore -keystore myService.keystore-keyalg RSA
这时我们就可以在文件夹keytool下,看到myService.keystore的证书库了。
2) 查看证书库myService.keystore的信息,我们可以使用的命令是:
keytool -list -v -keystore myService.keystore
3) 将证书库myService.keystore的myStore证书存储到文件owenfile中。执行命令是:keytool -export -alias myStore -keystore myService.keystore -rfc-file owenfile
所以我们在keytool的文件夹下可以看owenfile的文件。(注:上面的命令也可以这样写:keytool -export -alias myStore -keystore myService.keystore-storepass 123456 -rfc -file owenfile)
4) 将证书myStore导入到owenfile.cer的文件中,生成的是安全证书。执行命令是:
keytool -export -alias myStore -keystore myService.keystore-storepass 123456 -rfc -file owenfile.cer
注:通过(3)(4)的对比,我们可以看到在keytool的文件夹下的两份证书的不同形式。
5) 通过证书文件来查看证书,可以用的命令是:
keytool -printcert -file owenfile.cer
7. 总结
以上就是keytool的相关概念和基本用法了。现在我们应该明白了证书里面是包含什么东西了,无非就是对商家的信息进行加密,然后凭借着加密过的证书来互相之间的识别。在我们CPS的系统中,我们一般会把证书放到接口所在的服务器,因为我们的系统是分布式架构,所以可能对于不同的业务会部署在不同的服务器上。正常情况下,证书的认证就是需要接口的相关方法来识别的,所以我们就是将证书存放在了与接口所部署的服务器上,这样,只要有第三方访问我们的系统,我们就可以先验证他们的证书,只有证书正确了我们才可放行,这也是为了安全而考虑的。