基于SpringBoot的双向HTTPS认证配置

一、最终效果

  HTTPS双向认证,不仅仅需要用户浏览器校验服务器数字证书,还需要服务器端验证用户是否是可信的,在诸如金融、军事等涉密领域,非常讲究系统的安全性,理应杜绝任何其他无关用户访问服务器。
  对于HTTPS的基础知识在此不再赘述,在完成最终的HTTPS双向认证配置后,用户端访问服务器时,用户端浏览器会让用户选择自己被服务器信任的证书,来完成用户端的认证,如下图:
Chrome选择证书

二、步骤

2.1 单向认证

先从单向认证入手,理清楚基本的概念和脉络。

  单向认证指的是“服务器端认证”,指的是当客户访问服务器的时候,客户方去校验服务器是否是自己想去访问的服务器,我们一步步来。

2.1.1 创建SpringBoot项目

  利用Intellij IEAD,我们可以轻松便捷的创建各种版本的Spring Boot项目,点击File—>New—>Project,切换到Spring Initializr。
Spring Boot项目创建
   在Dependencies中把Web的Spring Web Strarter选中,其余的配置默认即可,于是便创建了项目“com.example.demo",目录结构如下:
Spring Boot目录

2.1.2 利用keytool生成密钥库(keystore)

  Keytool是Java用于管理密钥和证书的工具,其功能包括:

  • 创建并管理密钥
  • 创建并管理证书
  • 作为CA为证书授权(比如可以自己给自己的证书授权)
  • 导入导出证书

  密钥库指的是可以存放密钥的一个库,创建的密钥或者证书总需要一个地方存着吧,所以keytool决定在密钥库里面存放公钥,私钥或者数字签名,再配合着一套keytool的命令去进行密钥库的管理。
  在CMD运行下面命令,在C盘的当前用户文件夹里(如:C:\Users\CharlesChen)会生成"server.p12"文件。

keytool -genkey -alias server -keyalg RSA -keystore server.p12 -validity 360 -storepass 123456 -storetype PKCS12 -keysize 2048 -dname "CN=localhost, OU=localhost, O=localhost, L=CD, ST=CD, C=CN"

  简单解释下:

  • -genkey:创建keystore和密钥对(看做创建一张SQL表,-genkeypair与此命令没有差别)
  • -alias:和keystore关联的别名(为新纪录添加GUID)
  • -keyalg:加密方式
  • -validity:该密钥的有效期为 180天(默认为90天)
  • -storepass:存取密码
  • -storetype:密钥库类型
  • -keysize:密钥长度
  • -dname:证书个人信息(CN:commonName服务器域名、OU:organizationUnit、O:organizationName、L:localityName、S:stateName、C:country)
    更多细节可以参考其他博客《证书及证书管理(keytool工具实例)》

2.1.3 对SpringBoot进行配置

  首先把创建的"server.p12"文件放在resources同级目录下,然后在applicaiotn.preperties里写入如下配置:

# 服务器端证书检验
server.ssl.key-store=classpath:server.p12
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=server

  至此,我们便完成了服务端认证的配置。

2.1.4 测试

  启动项目后,我们利用Chrome浏览器访问https://localhost:8080,如下图:
访问单向认证的https
  之所以会报错,是因为该服务器的证书是我们自己签发的,在浏览器信任的CA列表中并没有我们自己。

2.2 双向认证

基于单向认证,怎样才能实现“客户端认证”?

  双向认证的流程大体是:

  • 用户生成自己的数字证书(不是密钥库,不过数字证书可以从密钥库导出,可以理解为没有私钥的密钥库)。
  • 用户端安装自己的数字证书。
  • 服务器端在密钥库中添加对用户端数字证书的信任。

2.2.1 利用keytool生成用户端密钥库并安装

  现在我们转换角色成为一个需要证明自己是自己的客户,同样,客户需要生成他自己的密钥库,命令如下:

keytool -genkey -alias client -keyalg RSA -keystore client.p12 -validity 360 -storepass 123456 -storetype PKCS12 -keysize 2048 -dname "CN=client, OU=client, O=client, L=CD, ST=CD, C=CN"

  生成密钥库后,双击并安装自己的证书,相当于你出门要把身份证带在身上,光有身份证还不行,如下图:
安装客户端证书

2.2.2 导出用户端数字证书

  运行下面命令,可在C盘的当前用户文件夹里会生成"client.cer"文件。

keytool -keystore client.p12 -export -alias clent -file client.cer

  简单解释下:

  • -keystore:选中的密钥库
  • -file:导出格式

2.2.3 服务器端信任用户端数字证书

  运行下面的命令,把导出的client.cer数字签名证书加入到服务器密钥库里面,让服务器信任用户证书。

keytool -import -file client.cer -keystore server.p12

  我们输入下面命令可以查看最终服务器密钥库的密钥列表:

keytool -list -keystore server.p12 -storepass 123456 -storetype PKCS12

  在下图中我们可以看到,在server.p12中有一个包含了私钥的实体,还有个来自客户端的信任实体。
密钥库列表

2.2.4 配置Spring Boot

  在application.properties里面添加下面的配置,启用客户端校验,并说明密钥库位置。

# 客户端证书校验
server.ssl.trust-store=classpath:server.p12
server.ssl.trust-store-password=123456
server.ssl.trust-store-type=JKS
server.ssl.trust-store-provider=SUN
server.ssl.client-auth=need

2.2.5 测试

  利用Chrome登录后我们发现会让用户选择自己的证书,这样会让服务器在自己的信任库里面搜索,如下图:
Chrome选择证书  项目代码已上传到码云Gitee:https://gitee.com/blackbuttoncc/two-way-HTTPS-demo

三、思考

如何证明你是你自己,每次想起就头疼!

  值得一提的是,上述步骤只是配置了HTTPS,但是没有禁止HTTP连接,所以后续优化步骤可以是强制所有的连接强制使用HTTPS,可参考文章《springboot–http跳转https》,在此不再赘述。
  最后,如果真的决定在生产环境中配置在应用中验证双向HTTPS验证,推荐分离服务器端的原始密钥库和信任库。例如,在本文中,是在服务器密钥库配置的信任实体,最好可以分离为server.p12和trust.p12两个库,这样可以很方便的维护。

四、参考文献

  1. 《使用keytool 生成证书》,作者:美码师
  2. 《证书及证书管理(keytool工具实例)》,作者:南极山
  3. 《Keytool工具生成SSL证书以及在Java中实现SSL》,作者:Obito_uchiha
  4. 《Springboot的SSL双向认证》,作者:得谷养人
  5. 《springboot–http跳转https》,作者:乐兰特
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值