springboot 启动 ssl_关于ssl(https)客户端配置

47688f6607384ef2b864cb117b3dcdbb

关于ssl(https)客户端配置

最近接触到银行的接口,对于安全方面非常严格,发到银行的报文需要加签、加密,接口也是ssl双向认证,只接受OVSSL以上的证书,这里记录下作为客户端ssl认证的两种方式。

银行会给一个他们的ssl公钥,这个公钥是用来验证他们返回报文的

因为银行测试环境还没有申请下来,所以也写了个本地的https服务端作为认证测试

客户端ssl证书生成

傻瓜式界面操作,需要软件KeyStore Explorer。

下载后新建-选择JKS(其他也可以)

7b478771d03745ffba72b7e6aa17b170

Tools->Generate Key Pair,生成密匙对

43ac43cbfa734924a25912b6490e4346

选择RSA(2048),点击Name输入网站信息

5ea7956aa0f14189a40d9288c6c73399

这里需要注意,Common Name 要对应接口域名或者ip。

80724b65e5844562ae0febe3c383ad2b

接下去就是下一步下一步,遇到密码就输入密码,然后保存到本地一个文件,比如127.0.0.1-ssl-client.jks。这里会有两次输入密码,第一次是密钥的密码,第二次是jks文件的密码,一般用一样的就行。

导出公钥:KeyStoreExplorer里面双击密钥对,点击pem,export,导出公钥pem文件,比如命名为127.0.0.1-ssl-client-pub.pem

48f96f7ab95940db99d25fb95bdd8e05

然后把这个127.0.0.1-ssl-client-pub.pem文件给银行,银行加入到他们的信任列表里面,我们就可以调用他们的接口了。(当然这里只是为了测试,真实情况需要把证书发给CA认证才行)

客户端把银行的公钥加入信任列表

银行给的公钥是pem格式的,假设叫citi-ssl-pub.pem,需要把这个公钥加入信任密钥对(KeyStore)。

打开KeyStore Explorer,新建->选择JKS->Tools->Import Trusted Certificate,选择银行的公钥citi-ssl-pub.pem

ef8c5c94f5f14fd98124169a5e78e590

保存,填写密码,这个也是jks文件的密码,保存文件可以叫127.0.0.1-ssl-client-trust.jks

客户端代码直接请求https接口

上面我们有了客户端ssl证书、也把公钥给了银行、银行把公钥给我们,我们也生成了信任jks。可以开始写代码了。这里用hutool的httpUtil工具类请求银行接口,直接上代码

3ba377d9e23b45a1be0371c3a1753327

这里代码写好了,当然运行肯定回报错,银行的测试环境没有,我们这里再模拟写一个https的服务,作为测试。

https服务端ssl证书生成

同客户端一模一样,也需要导出公钥,假设叫127.0.0.1-ssl-server-pub.pem。把这个也加入到127.0.0.1-client-trust.jks作为信任证书,方法同加入citi-ssl-pub.pem一样。这样127.0.0.1-client-trust.jks里面就有两个信任证书了

https服务端把客户端ssl证书加入信任列表

这里的步骤也和客户端一样,生成一个jks密钥对,加入客户端的ssl公钥证书(127.0.0.1-ssl-client-pub.pem)。这里是模拟银行把我们的公钥拿过去后的操作。服务端的信任jks文件名:127.0.0.1-ssl-server-trust.jks

整理下所有的测试证书文件

ssl                                        ssl文件夹|---client                                客户端ssl文件夹|---|---127.0.0.1-ssl-client.jks        客户端ssl密钥对,包含私钥|---|---127.0.0.1-ssl-client-pub.pem    客户端ssl公钥证书|---|---127.0.0.1-ssl-client-trust.jks    客户端信任证书(包含两个公钥证书)|---server                                服务端ssl文件夹|---|---127.0.0.1-ssl-server.jks        服务端ssl密钥对,包含密钥|---|---127.0.0.1-ssl-server-pub.pem    服务端ssl公钥证书|---|---127.0.0.1-ssl-server-trust.jks    服务端信任证书列表|---|---citi-ssl-pub.pem                银行ssl公钥证书

本地模拟https服务端代码

springboot 项目,在配置文件中增加ssl

server:  port: 4000  ssl:    key-store-type: JKS    key-store: classpath:ssl/server/127.0.0.1-ssl-server.jks    key-store-password: 127    key-password: 127    trust-store-type: JKS    trust-store: classpath:ssl/server/127.0.0.1-ssl-server-trust.jks    trust-store-password: 127    client-auth: need

服务端接口代码,非常简单

@RestControllerpublic class SslServer {    @RequestMapping("/ssl")    public String hello(@RequestParam("host") String host) {        return "hello " + host;    }}

启动服务端项目

测试客户端直接请求服务端

运行客户端main方法,直接请求,正常返回
7c847b22d5d34ea88befe7b69883021a
服务端没有加入客户端信任证书测试

修改服务端的信任证书列表,将127.0.0.1-ssl-client-pub.pem证书删掉

3dead68eb86c4e8f8e9588858d94208f

增加citi-ssl-pub.pem(不能为空),再次请求

e6eb8e03ac0d4f8fa538058df2f5a288

如果没有把客户端证书加入到服务端信任列表,请求就会报错。还原服务端的信任证书列表

把客户端的信任列表去掉

客户端代码改为

76df2e2af0ad4017997b4d381a8e9dd4

再次请求,发现还是能正常访问,那么客户端的信任列表有什么用呢?我的理解是为了验证服务端的响应是否为银行,防止返回的报文被他人篡改

客户端http请求nginx,nginx转发银行

这种情况是为了应付如果项目部署服务机器不能访问外网,可以通过nginx转发。如果是这种方式代码就不需要配置任何东西,请求nginx的端口就行这种情况nginx配置文件

http{    server{        listen    80;        server_name    localhost;        location /bank {            proxy_set_header Host $host;            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_redirect    off;             proxy_ssl_certificate        127.0.0.1-ssl-client-pub.pem;            proxy_ssl_certificate_key    127.0.0.1-ssl-client-pri.pem;            proxy_ssl_trusted_certificate     127.0.0.1-ssl-server-pub.pem;            proxy_ssl_verify     on;            proxy_ssl_server_name on;            proxy_ssl_verify_depth 2;            proxy_pass   https://127.0.0.1:4000/ssl;        }    }}

这里的127.0.0.1-ssl-client-pub.pem 和127.0.0.1-ssl-server-pub.pem 和原来的一样,但是需要一个客户端ssl证书密钥,也可以通过keyStore Explorer导出

右键选择密钥对->View Details->Private Key Details->输入密码->点击pem->Export

8f56a26625bf440da3c804bb0e3ae6c8

还存在一个疑问没解决:127.0.0.1-ssl-server-pub.pem 这个公钥如果Common Name不是域名,nginx转发会报错,upstream SSL certificate does not match "127.0.0.1" while SSL handshaking to upstream

代码可以在Github上找到

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值