赵志浩
Published on 2025-08-09 / 23 Visits
4
0

公开密钥基础设施(PKI)

非对称加密中,公钥可公开分享,但存在致命问题:“如何证明某个公钥确实属于它所声称的拥有者?”

举个例子:想象你要给马云转账,他公开了自己的支付宝账号(类似公钥)。但黑客在中途把账号替换成自己的,于是你的钱转给了黑客。

在网络世界中:

服务器声明:“我的公钥是 Pub_A”

但黑客在传输途中将其替换为 Pub_Hacker

你加密的数据用 Pub_Hacker 加密 → 黑客能用自己私钥解密

黑客再用 真正的Pub_A 加密数据转发给服务器 → 全程不被察觉

这就是经典的 中间人攻击(Man-in-the-Middle Attack),而漏洞根源在于:公钥本身无法自证身份!

🛡️ PKI 的解决方案:数字身份证

PKI 通过引入 数字证书(Digital Certificate) 解决此问题,原理如同现实中的身份证:

现实世界                  数字世界
公安局                 证书颁发机构(CA)
身份证                 X.509 数字证书
身份证照片+姓名            绑定的域名+公钥
公安局公章          CA的数字签名

📜 数字证书的关键结构:

证书内容:
  主题: www.alibaba.com    # 声明身份
  公钥: Pub_A             # 服务器的公钥
  签发者: DigiCert CA     # 担保机构
  有效期: 2023-2024       # 时效限制
  扩展信息:               # 其他约束
    - 仅用于SSL加密
    - 禁止代码签名
---------------------------
数字签名:                 # CA的防伪印章
  用DigiCert的私钥对以上所有内容签名

🔍 客户端如何验证?
当浏览器收到证书时,执行三重验证:

💡 关键点:签名验证

  1. 浏览器用内置的 CA根证书公钥 解密签名

  2. 对比解密出的哈希值 vs 证书实际内容的哈希值

  3. 匹配 → 证明证书未被篡改且由CA签发

  4. 域名绑定

  5. 确保证书中的 www.alibaba.com 与你访问的域名一致

  6. 防止证书被挪用(如用百度证书伪装阿里)

PKI 的核心是什么呢,我这里简单描述一下:

  1. 证书颁发机构(CA):CA 是负责发放和管理数字证书的权威机构即可。任何人包括你我都可以签发证书,只是不权威罢了。权威的 CA 证书全世界数量是可数的,可数,就意味着可以不通过网络,而是在浏览器与操作系统出厂时就预置好。

上图是 Windows 系统预制的CA 证书。

所以可以理解为,我们的电脑或者浏览器,最初就预埋了权威 CA 机构的根证书,或者说权威 CA 机构的公钥数据。

  1. 我们的服务器首先 先去对应的证书颁发机构处申请对应的证书,这个过程大概就是:你需要首先先给证书颁发机构证明,你的确是这个域名的所有人,这样 CA 才会给你这个域名颁发对应的证书。

此时一般是 CA 会要求你去在你的域名解析处,增加新的 DNS 解析,比如:增加一个 txt 的解析,txt 的解析内容就是当前 CA 给你规定的内容。

此时 CA 机构会去访问你的域名进行 txt 解析,解析出的结果和给你指定的存放内容完全一致,表明你当前就是该域名对所有人。

然后你的服务器一般需要使用 openssl 通过 RSA 算法或其它非对称加解密算法,生成公私钥对。

此时把你的公钥和你的身份信息(域名)请求 CA 机构,给你生成对应的证书。(自己的私钥还是要在自己的服务器上留存好)

此时给你颁发的证书,大概是这样一个形式:

证书内容:
  主题: www.alibaba.com    # 声明身份
  公钥: Pub_A             # 服务器的公钥
  签发者: DigiCert CA     # 担保机构
  有效期: 2023-2024       # 时效限制
  扩展信息:               # 其他约束
    - 仅用于SSL加密
    - 禁止代码签名
---------------------------
数字签名:                 # CA的防伪印章
  用DigiCert的私钥对以上所有内容签名

该证书当中,有你的域名信息,以及签发者的 CA 机构信息,以及你服务器的公钥信息,以及证书过期时间。最后是针对你当前这个证书生成签名,该签名是通过 CA 机构的私钥生成的签名。(先将证书内容生成摘要,然后再通过 CA 机构的私钥,生成签名。具体使用的算法其实也会写到证书里面,这样客户端就可以通过证书中指定的算法进行验签了。)


当浏览器客户端访问你这个域名的时候,你首先把这个证书的信息发给客户端,客户端此时本机由于已经预先安装了全世界所有权威 CA 机构的公钥信息。

此时会根据本机的 CA 机构公钥,来验证你所发出来的这个证书签名是否是合法的。验证签名通过,表明你这个证书是权威 CA 机构颁发,且未经篡改的证书。

此时会去解析你这个证书中的内容,验证证书有效期,以及该证书所颁发的域名的确是当前所访问的域名,此时则获取到该域名中的公钥数据,然后后续和你这个服务端的所有信息交互,都会先通过该公钥进行加密然后发给你服务端,服务端通过自己的私钥进行解密即可。

此时就建立了一个比较安全的信息通道了。


我们上面提到通过使用本机预埋的 CA 机构的公钥来验证证书的有效性,然后获取到了对应的服务器公钥,此时所有和服务器的交互,都可以通过该公钥加密后给到服务器。

上述的操作可能会产生的一个问题是:

  1. 如果服务端的私钥被泄露。那么所有的历史通信都会被破解掉。

这是一个比较严重的问题,所以当客户端验证服务端下发的证书合法并提取出对应的服务器公钥后,此时实际是要走一个密钥交换流程。这里的密钥交换流程,实际就是进行当前的会话密钥协商。

通过使用 ECDH 协商出来一个新的对称加解密的密钥,此时后续的所有会话全部使用该密钥来进行加密给到服务端,服务端则也是使用该密钥来进行解密。

这样的话,就算该密钥泄露,也只会影响这一次会话的信息被解密。

相比于服务端的私钥泄露,而导致的所有会话都被泄密要安全的多。!

而此处协商密钥的核心,其实也很简单,也就是上面 DeepSeek 生成的这个图

  1. 当服务端发送证书给客户端后,客户端通过 CA 验证证书合法性以及从证书中提取出对应的公钥后。

  2. 此时服务端生成一个临时的公钥和私钥,并通过自己最初的私钥进行签名,然后将这个公钥信息发送给客户端。

  3. 此时客户端收到服务端发送的临时公钥和签名后,先根据从 CA 证书中获取到的公钥验证该签名,验证通过后,表明该信息没有被篡改,此时提取出云端下发下来的临时公钥。

  4. 然后客户端也生成临时的公私钥,并把自己的公钥也发送给服务端。

  5. 此时客户端拥有:服务端的临时公钥、以及自己生成的临时私钥。

  6. 此时服务端拥有:客户端的临时公钥,以及自己生成的临时私钥。

  7. 然后客户端通过 ECDH(服务端的临时公钥,以及自己生成的临时私钥)可以生成一个新的密钥 key

  8. 服务端此时也通过 ECDH(客户端的临时公钥,自己生成的临时私钥)然后也可以生成一个新的密钥 key

该服务端通过 ECDH 生成的密钥 Key 此时和客户端通过 ECDH 生成的密钥 Key 是相同的同一个 Key!(这也就是 ECDH 椭圆曲线算法的有趣之处)

  1. 此时客户端和服务端分别协商出了一个相同的密钥 key,该密钥 key 就是后续进行会话时使用的对称加解密的 key 了。

通过上述 ECDH 的密钥协商方式,客户端的临时私钥并没有通过网络发送出去,只有本地自己知道。而服务端生成的临时私钥也并没有通过网络发送给客户端,也是只有自己知道,所以两边生成的临时私钥都是绝对安全的。

此时通过 ECDH,使用自己的临时私钥和对方的临时公钥 ,可以生成一个相同的密钥 Key,该密钥 Key 就是后续会话进行加密使用的会话密钥。

所以就非常的安全,非常的 Nice 了!


参考地址:https://chat.deepseek.com/a/chat/s/7dc333a1-3311-41e6-80d8-9952d9737548

凤凰架构:https://icyfenix.cn/architect-perspective/general-architecture/system-security/transport-security.html

区块链技术指南:https://topgoer.cn/docs/blockchain_guide/blockchain_guide-1emusrrq934r8


Comment