成长在于积累——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. 对于前线兄弟的支持,目前做的不到位。当问题不清晰,责任不明确时,技术人员不会主动去协助,导致项目经理和测试人员很被动。因此项目中的技术负责人,还是很有必要的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/160012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencv- CLAHE 有限对比适应性直方图均衡化

CLAHE(Contrast Limited Adaptive Histogram Equalization)是一种对比度有限的自适应直方图均衡化技术,它能够提高图像的对比度而又避免过度增强噪声。 在OpenCV中,cv2.createCLAHE() 函数用于创建CLAHE对象,然后可以…

宝宝照片保存大法!一键制作照片书

亲爱的家长们,你们是否为宝宝成长过程中的各种美好瞬间而感到兴奋和感动?宝宝的笑容、第一次学步、第一次叫妈妈爸爸……这些珍贵的瞬间,我们都想把它们永远保存下来。现在,我们有一款神奇的工具,一键制作照片书&#…

还不知道指针和引用的区别,一篇文章教会你

1、引用的概念 1.引用不是新定义一个变量,而是给已存在变量取了一个别名 2.编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间 比如:孙悟空,可以叫他孙悟空,也可以叫齐天大圣。本质他们就是一个人 2、引用的定…

[nlp] RuntimeError: Llama is supposed to be a BPE model!报错解决

# tokenizer AutoTokenizer.from_pretrained(BASE_MODEL) 改成这个legacyFalse, use_fastFalse: tokenizer AutoTokenizer.from_pretrained(BASE_MODEL, legacyFalse, use_fastFalse)

【C++初阶】STL详解(五)List的介绍与使用

本专栏内容为:C学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C 🚚代码仓库:小小unicorn的代码仓库&…

vs调试输出,不显示线程已退出

如题:一堆线程退出的信息,招人烦。 其实在vs设置里可以关闭: 工具-->选项-->调试-->输出窗口:

java--ArrayList快速入门

1.什么是集合&#xff1f; 集合是一个容器&#xff0c;用来装数据的&#xff0c;类似于数组。 2.有数组&#xff0c;为啥还学习集合 ①数组定义完成并启动后&#xff0c;长度是固定了。 ②集合大小可变&#xff0c;开发中用的更多。 3.ArrayList<E> 是用的最多、最…

Linux C 基于tcp和epoll在线聊天室

基于tcp和epoll在线聊天室 说明服务端代码 说明 服务端&#xff1a;实现了验证用户是否已经存在&#xff08;支持最大64用户连接&#xff09;支持广播用户进入退出聊天室以及用户聊天内容。   这里只提供里服务端代码&#xff0c;如果想要看客户端代码点击这里。 服务端代码…

LINUX入门篇【8】----计算机组成原理以及OS知识的总结

前言&#xff1a; 从而本篇文章开始&#xff0c;我们将进入LINUX的进程篇&#xff0c;但学习进程之前&#xff0c;我们首先需要重新认识我们的计算机&#xff0c;并且正确认识到控制进程的OS&#xff0c;即操作系统是怎样在计算机运行的过程中起到作用的。下面就让我们一同去了…

规则引擎Drools使用,0基础入门规则引擎Drools(一)基础入门

文章目录 系列文章索引一、规则引擎概述1、引出问题2、什么是规则引擎3、使用规则引擎的优势4、规则引擎应用场景 二、Drools介绍1、Drools概述2、Drools构成3、相关概念说明4、Drools执行过程5、KIE介绍 三、Drools入门案例1、业务场景说明2、开发实现 四、Drools基础语法1、规…

D. Secret Santa(构造)

首先n点n边&#xff0c;是一个基环树&#xff0c; 可以观察得到其实最大值是不变的 剩下的人自己随便找个人匹配即可 所以关键是构造一个方案解决匹配到自己的情况 找到所有没送出礼物的人&#xff0c;然后直接匹配&#xff0c;如果匹配到自己 因为没有送出礼物的人想送出…

配置静态 Eth-trunk

1、需求 1&#xff09;交换网络中存在2个 VLAN – 10 和 20 2&#xff09;每个VLAN的IP地址为&#xff1a;192.168.xx.0/24&#xff08;xx为 vlan 号&#xff09; 3&#xff09;对交换机之间的链路进行链路捆绑&#xff0c;增加互联带宽 4&#xff09;确保同 VLAN的 PC 之间互…

【Web实战】浅谈reactor netty httpclient请求解析过程

目录 0x00 前言 0x01 "畸形scheme"HTTP请求 0x02 其他 0x00 前言 Reactor Netty HttpClient 是 Reactor Netty 框架提供的一个用于进行异步 HTTP 请求的客户端库。它基于 Reactor 框架&#xff0c;采用响应式编程模型&#xff0c;允许以非阻塞的方式执行 HTTP 请…

如何通过RA过程识别Redcap UE?

以下是38.300中的描述 RedCap UE可以通过发送MSG3/MSGA的特定LCID识别&#xff0c;可选条件是通过MSGA/MSG1的PRACH occasion/PRACH preamble识别&#xff0c;根据这段描述&#xff0c;通过MSG3/MSGA的识别是必须项&#xff0c;而MSGA/MSG1的识别过程是可选项。如果通过MSGA/MS…

三极管基础知识

三极管 基本概念应用电路 基本概念 三极管 NPN 和PNP 电流方向 PNP是从e 流向 b c NPN是从 b c流向e 应用电路 箭头出发方向的电极比箭头指向方向的电极&#xff0c;高0.7v才导通。 NPN控制下游是否接到地&#xff0c;PNP控制上游的电源能否接过来。

笔试题之指针结合数组的精讲2

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

【Python大数据笔记_day11_Hadoop进阶之MR和YARNZooKeeper】

MR 单词统计流程 已知文件内容: hadoop hive hadoop spark hive flink hive linux hive mysql ​ input结果: k1(行偏移量) v1(每行文本内容)0 hadoop hive hadoop spark hive 30 flink hive linux hive mysql map结果:k2(split切割后的单词) v2(拼接…

webpack plugin

1、基本写法及使用 这里用到 emit 钩子 及make 钩子&#xff0c;前者是串行后者是并行 /*** 1.webpack加载webpack.config.js中所有配置&#xff0c;此时就会new TestPlugin()&#xff0c;执行插件的constructor2.webpack创建compiler对象3.遍历所有plugins中插件&#xff0…

灵活运用Vue 3中的setup函数—深入解析Composition API

新建项目&#xff0c;项目主入口为App.vue&#xff08;主组件&#xff09;&#xff0c;新建child.vue&#xff08;子组件&#xff09;。 1.1 setup 执行 时机问题 1.在主组件里引入子组件和ref&#xff1a; import {ref} from vue import child from ./components/child.vue2…

uni-app项目细节记录

js字符串插值 使用反引号,内容使用${参数} url:/pages/login/index?name${this.name}&passwd${this.passwd}