curl: (60) Peer‘s Certificate issuer is not recognized

问题描述

        新写了一个Https接口,由于是get请求,所以自己在浏览器上访问了下,是可以请求到的,以为没事了,没想到交付的时候,第三方通过curl请求,显示接口不可访问了,具体报错如下:

前言

        网上几乎所有的教程都说是由于证书过期,或者缺少证书的原因。证书有问题确实会造成上述情况,但不是唯一的因素。

        如果大家遇到了相同的问题,建议先看其他的博客确保把证书配置正确,在确保证书是绝对没有问题的情况下,在确保证书是绝对没有问题的情况下,在确保证书是绝对没有问题的情况下,可以再来看看是否和我相同的情况导致的。

问题原因

        根本原因是客户端发起的是https请求,而服务端接收到的时候变成了http的请求。因为服务端根本不知道此次是https请求,自然不会返回自己的证书给客户端,所以客户端提示说证书可能丢失或过期了,即得到Peer's Certificate issuer is not recognized的提示信息。

问题发现

        如何确定自己接手到的是http请求还是https请求呢,首先可以在接口代码中打印请求的协议,也可以在ngixn请求日志中打印。

        我是在nginx中打印日志发现了这个问题。新写的接口请求逻辑是这样的。

        客户端通过域名发起Https请求-->网关(进行域名解析映射至ip服务器)-->服务器nginx(得到请求后代理至最终服务)-->最终服务。

        我们这里存在的问题是网关-->nginx这一步,我们的it人员把https协议映射成了http协议,因此出现了问题。

Https原理

        发现这个问题是由于仔细阅读了https协议的过程及原理,然后进行了总结,一并发出来。

1、客户端发起请求,告诉服务端自己支持的hash算法(用来验证信息是否被篡改)和非对称加密算法(用来进行认证期间信息的加密);

2、服务端找到匹配支持的算法,将证书发送给客户端(证书中包含着非对称加密算法的公钥);

3、客户端拿到证书后,利用证书的公钥进行解密,验证证书的合法性,通过后拿到非对称加密的公钥;

4、客户端生成一串随机数密码,握手消息、握手消息取hash值,然后用随机数密码对(握手消息+握手消息hash值)进行加密得到加密握手消息,将随机数密码用公钥进行加密以及加密握手消息这两部分传输到服务端;

5、服务端利用私钥进行解密得到随机数密码,通过随机数密码解密客户端传输过来的加密握手消息,然后对握手消息取hash,判断hash是否一致(防止信息在传输过程中被篡改);

6、服务端生成握手消息,使用随机密码串加密(握手消息+握手消息hash值)传输给客户端。

7、客户端得到后利用加密字符串进行解密,判断是否hash一至。一致则说明信息传输过程中没有被篡改,,且加密字符串只被客户端、服务端所知晓,此后的信息传输使用加密字符串进行对称加密即可。

写在最后

        未修改之前,使用postman测试接口,如果禁用了ssl认证,则接口可以访问成功;如果开启ssl认证,则接口访问失败。所以我推测,浏览器进行url访问的时候,可以自动切换成禁用ssl的方式请求接口,因此最开始我本地进行测试的时候才没有问题。

        但是关于浏览器可以访问的根本原因我不是很清楚,大家如果知道的话请交流指教下。

        以后还是乖乖的用postman测试接口吧。