成长在于积累——https 认证失败的学习与思考

1. 引言

本周二长城项目在收尾过程中,出现了一个车端无法进行注册的问题:curl提示证书认证失败(其实已经能确认问题方向了,运维人员去确认证书问题即可)。虽然最终的原因是由于长城运维人员导致的。但是这个过程让我颇受"感动"。

  1. 问题出现的当天,运维人员没有思路,导致现场测试,开发人员一起调试到晚上10点。
  2. 当我们咨询长城人员是否对服务器进行修改时,由于我们并不能明确说明问题点。导致客户一直不会主动去响应。(属于双方的问题)
  3. 问题定位的不明确。导致项目经理问题推进不顺利以及消耗我们内部许多资源。(属于我们技术支持不到位)

经过此事,我觉得打铁还需自身硬。虽然问题的原因是因为客户做了修改。但是我们却一直不能定位到问题。这就属于我们的能力问题了。

本文,主要是想分享一下该问题的分析思路,以及证书认证相关的知识。希望能对同事们有所帮助。

2. 问题复现过程

问题日志截图如下:

图一:车端注册,平台反馈失败

从图中,我们可以得出,curl 错误码51(认证失败)。

应对措施:请运维人员进行证书相关的排查

运维人员进行了操作之后,得出结论:并没有对证书进行修改,并且他自己通过curl 指令,在服务器中是可以访问成功的。如图:

图二:运维人员在服务器上,进行验证

之后就没有下文,问题就卡住了(当时我的内心是崩溃的)。我用同样的根证书,客户端证书,客户端密钥,都是无法访问成功的(拒绝连接)。后来我猜测应该是平台当时建立了路由规则,可惜没办法验证了。

图三:尝试连接OTA 平台服务器,却被拒绝访问

问题挂在这里,过了几天,客户终于重视了这个问题,派了对方的运维人员进行查看。花了半个小时,问题就解决掉了。

图四:客户问题定位

虽然定位的不一定准确,但是可以确定的是:服务器的根证书有问题。

经过此事,我花了点时间,查阅网上资料,以及请问通知,总结了https 认证过程中的一些知识点。总结之后,感觉之前还是自己知识面窄了,导致浪费了不少的资源。

3. 知识点总结

3.1 名词介绍

对于初学者,建议先了解一下名词。

|------|----------------------------------------------------------------------------------|
| 名词 | 解释 |
| 证书 | SSL协议中的证书,其主要功能有两点。 1. 身份验证 2. 数据加密传输 因此证书中一般包含以下信息:公钥,持有者信息,证书认证机构的CA信息,证书有效期等。 |
| 单向认证 | 单项认证是我们平时用的比较多的访问方式。比如我们访问百度网站,采用的就是单项认证。浏览器只需要认证服务端的合法性即可。 |
| 双向认证 | 顾名思义,客户端不仅要验证服务器的合法性。服务器也要验证客户端的合法性。 |
| 证书链 | 一个证书列表,若对端证书授权于列表中其一,则认为对端证书可信 |
| 根证书 | 根证书其实就是CA认证中心的一种体现。若本地信任该证书,即表明信任该CA认证中心相关的下属证书。 |
| 自签证书 | 用自己生成的根证书,签发证书。但是这种证书对于一般的平台是不可信的。 |
| 商签证书 | 与自签证书相反。使用的是商业根证书,签发证书。由于商业根证书一般是被大众所信任的。根据证书链的原理,签发的证书也就被信任。 |

3.2 单向认证和双向认证

我们在不同的项目中,与平台之间的交互形式是不一样的。有单向认证和双向认证。

3.2.1 单向认证

单向认证的过程:客户端从服务端下载服务器端公钥证书,依据自己本地证书链,进行验证。若验证成功,则建立安全通信通道。

服务端需要保存公钥证书私钥 两个文件。客户端只需要保存证书链即可。

图五:单向认证流程

3.2.2 双向认证

双向认证的过程:客户端除了需要将服务端的公钥证书下载,与本地证书链进行验证外。还需要将客户端的公钥证书上传到服务端,服务端用自己的根证书进行验证,等双方都认证通过了,才开始进行数据传输。

服务端需要保存根证书 (用于校验客户端证书的合法性),服务器的公钥证书 ,服务器的密钥文件 。客户端需要保存客户端证书文件 ,客户端密钥文件客户端证书链

图六:双向认证流程

3.2.3 牛刀小试

当了解认证的流程后,我们可以自己做一个自签证书流程,以加深印象。从上面的内容中,我们知道需要用到六个证书。

  • 服务器端公钥证书:server.crt
  • 服务器端私钥文件:server.key
  • 根证书:root.crt
  • 客户端公钥证书:client.crt
  • 客户端私钥文件:client.key
  • 客户端集成证书链:client_CA.crt

图七:证书关系图

3.2.3.1 生成自签名根证书
  1. 创建根证书私钥。openssl genrsa -out root.key 1024
  2. 创建根证书请求文件。openssl req -new -out root.csr -key root.key **。**注意:在创建证书请求文件的时候需要注意以下三点,下面生成服务器请求文件和客户端请求文件均要注意这三点:根证书的Common Name填写root就可以,所有客户端和服务器端的证书这个字段需要填写域名,一定要注意的是,根证书的这个字段和客户端证书、服务器端证书不能一样。其他所有字段的填写,根证书、服务器端证书、客户端证书需保持一致。最后的密码可以直接回车跳过。
  3. 创建根证书。openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650

得到了有效期为10年的根证书root.crt.我们可以用这个根证书去颁发服务器证书和客户端证书。

3.2.3.2 生成自签名服务端证书
  1. 生成服务器端证书私钥。openssl genrsa -out server.key 1024
  2. 生成服务器证书请求文件。openssl req -new -out server.csr -key server.key **。**证书请求文件中携带着公钥以及用户信息。但是证书请求文件是未加密的,任何人获取到之后,都是可以解析其中内容的。
  3. 生成服务器端公钥证书。openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650 **。**使用根证书私钥对证书请求文件内容进行加密,并在证书中添加其它参数。比如:说明该证书的CA机构(root.crt)。此时root.crt 文件是可以被解析的。但是获取到的是被加密之后的服务器公钥+服务器信息。以及签发的CA机构(root)。
3.2.3.3 生成自签名客户端证书
  1. 生成客户端的证书密钥。openssl genrsa -out client.key 1024
  2. 生成客户端证书请求文件。openssl req -new -out client.crs -key client.key
  3. 生成客户端证书。openssl x509 -req -in client.crs -out client.crt -signkey client.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650

3.3 握手过程(单向为例)

通过上面的单向认证以及双向认证的图解,我们已经有了初步的理解。现在加深一下理解。

  1. 客户端向服务器发起握手请求。该请求中包含了以下内容:
    1. 客户端 SSL 协议的版本号,
    2. 加密算法的种类,
    3. 以及其他服务器和客户端之间通讯所需要的各种信息。
  2. 服务端进行响应,其中包含了:
    1. SSL 协议的版本号,
    2. 加密算法的种类,
    3. 以及其他相关信息,
    4. 同时服务器还将向客户端传送自己的证书。
  3. 客户端接收到服务端的消息及证书之后,数字证书就要进行验证了。流程大致如下:
    1. 首先将证书进行解密,获取证书相关信息。
    2. 判断证书是否过期;
    3. 发行服务器的证书CA是否可靠;(主要查看该CA是否在客户端的信任列表中)
    4. 使用发行者的公钥机密服务器的数字签名。
    5. 判断证书上的域名是否和服务器的实际域名相匹配。
    6. 若以上都通过,则证书合法。并获取证书中的公钥。
  4. 客户端随机产生一个用于后面通讯的"对称密钥"R,然后用服务器的公钥对其加密,再发送给服务器。
  5. 客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤 4 中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。
  6. 服务器向客户端发出信息,指明后面的数据通讯将使用的步骤 4 中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。
  7. SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。

4. 思考

若遇上本次问题时,我已掌握上述知识点,我会有什么不同呢?分析:

  1. 由图一可知:curl 返回51 错误码。表示客户对服务器的证书没有认证通过。
  2. 其实已经将这个排查点通知客户:客户端验证服务器端证书失败,请问你们是修改服务器证书了吗?(最初可以直接对客户抛出这样的问题,但是由于我们自身不自信,若客户不理睬,我们也不会去催促他们)。到此,可以将问题抛给客户了。若更加专业点,可以进行步骤三。
  3. 获取服务器证书内容,将crt 进行解析:openssl x509 -in clientcert.crt -noout -text 。分析证书中的内容,找出认证失败的原因。这样客户就没有理由不理睬了。

后面也遇到了一个证书问题:下载阶段,车端无法下载固件包,但是通过浏览器进行下载,就可以将固件包下载

图8. 车端无法下载固件包

了解了上述的知识点后,我们就可以这样分析:

浏览器访问是单向认证,并且可以正常下载。(没有弹出警告),但是我们车端和云端之间采用的是自签证书。理应服务器的CA不在电脑的信任列表中的。因此,我们可以怀疑客户采用的证书是商用证书。结果也是如此。

图9. 客户的回答:CDN证书错误

总结

经过此次问题,我由两点感触:

  1. 知识面的提高,对于我们交付组成员而言是比较重要的。
  2. 对于前线兄弟的支持,目前做的不到位。当问题不清晰,责任不明确时,技术人员不会主动去协助,导致项目经理和测试人员很被动。因此项目中的技术负责人,还是很有必要的。
相关推荐
时光追逐者2 分钟前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb
一弓虽7 分钟前
SpringBoot 学习
java·spring boot·后端·学习
genggeng不会代码2 小时前
用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)
学习
搞机小能手2 小时前
六个能够白嫖学习资料的网站
笔记·学习·分类
Luck小吕4 小时前
两天两夜!这个 GB28181 的坑让我差点卸载 VSCode
后端·网络协议
ZVAyIVqt0UFji4 小时前
360 OpenStack支持IP SAN存储实现
网络·网络协议·tcp/ip·openstack
The_cute_cat4 小时前
25.4.22学习总结
学习
冰茶_5 小时前
.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架
学习·microsoft·微软·c#·.net·xamarin
帅云毅5 小时前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链
豆豆5 小时前
day32 学习笔记
图像处理·笔记·opencv·学习·计算机视觉