Skip to content

Commit

Permalink
Update principleofhttpsssl.md
Browse files Browse the repository at this point in the history
  • Loading branch information
minimouse0 authored Jan 21, 2025
1 parent bc6afb5 commit 303e9f7
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion docs/uncategorized/principleofhttpsssl.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ HTTP协议又被称为“超文本传输协议”。它用一套固定不变的

数学家和网络专家们协手研发了一种不需要传输所有加密规则的方式:非对称加密。通过于复杂的数学问题(如大数分解、离散对数等),可以实现加密和解密规则不相同。加密规则和解密规则虽然不同且互相之间无对应规律,但它们是成对生成的,一个公钥仅对应一个私钥。

接下来,我们将用客户端向网站服务器发送一条数据作为例子。在这个例子中,客户端是数据发送者,服务器是数据接收者。

于是数据接收者先将用于加密的公钥通过明文传输发送给数据发送者,然后数据发送者通过公钥加密数据,再将加密数据发送给数据接收者。随后,数据接收者用该公钥对应的私钥进行解密,就得到了数据发送者想要发送的数据。

在上面的过程中,公钥的发送采用明文传输,攻击者是可以看到公钥的具体内容的。然而他不具有私钥,而且非对称加密相比对称加密的最大优势就是其加密算法(公钥)无法用于反推解密算法(私钥),这样攻击者既不能直接获取私钥(因为数据接收者只公开了公钥而未公开私钥),又不能通过公钥反推出私钥。看起来,攻击者就没有任何办法解密数据了。
Expand All @@ -40,7 +42,7 @@ HTTP协议又被称为“超文本传输协议”。它用一套固定不变的

虽然攻击者不可以通过公钥直接解密数据,但是攻击者可以拦截公钥的发送,公钥就只发送给了攻击者,但没有被发送给真正需要接收它的数据发送者。这样,攻击者自己假装是服务器,自己生成一对密钥,然后向数据发送者发送自己的公钥。数据发送者收到了攻击者的公钥,但是攻击者将其伪造成了是原本的数据接收者提供的公钥,于是数据发送者用攻击者的公钥加密数据,然后发送给攻击者。攻击者由于持有该伪造的密钥对中的私钥,他便可以解密数据,数据发送者发送的数据便泄漏了。接下来还需要应对数据接收者那边,让他接收到正常的信息,防止攻击被他知道。于是攻击者自己伪装成数据发送者,用数据接收者提供的公钥加密数据发送者的数据并将其提供给数据接收者。这样,数据接收者收到的信息就是数据发送者的数据经自己公钥加密后的版本,接收者可以正常解密,而没有证据向他表明这些数据已经泄漏。

为了证明公钥确实来自数据接收者,发送者和接收者需要约定一个第三方,由他来向发送者证明接收者的密钥的真实性。首先数据接收者把本次要使用的公钥发送给这个第三方,这个第三方通过公钥和数据接收者的身份之间的绑定关系生成了另一串数据,这个数据就是数字证书,记录着公钥和数据接收者的对应关系。随后这个第三方将数字证书发给数据接收者,数据接收者再将证书发给数据发送者,数据发送者一看有这个第三方提供的证书证明了公钥确实来自真正的发送者,那么就可以证明这个中间没有人攻击,可以开始数据加密和传输了。如果有人用上面的方式攻击,那么公钥的提供者就会变成攻击者,数据接收者发现公钥的提供者和证书里的提供者对不上,就会停止此次操作,要求数据发送者重新提供公钥,直到攻击者不再截获公钥。这个过程中,这个第三方就是证书颁发机构(Certificate Authority,简称CA)。
为了证明公钥确实来自数据接收者,发送者和接收者需要约定一个第三方,由他来向发送者证明接收者的密钥的真实性。首先数据接收者把本次要使用的公钥发送给这个第三方,这个第三方通过公钥和数据接收者的身份之间的绑定关系生成了另一串数据,这个数据就是数字证书,https要求的数字证书是数字证书的一种:SSL证书。SSL证书中记录着公钥和数据接收者的对应关系。随后这个第三方将数字证书发给数据接收者,数据接收者再将证书发给数据发送者,数据发送者一看有这个第三方提供的证书证明了公钥确实来自真正的发送者,那么就可以证明这个中间没有人攻击,可以开始数据加密和传输了。如果有人用上面的方式攻击,那么公钥的提供者就会变成攻击者,数据接收者发现公钥的提供者和证书里的提供者对不上,就会停止此次操作,要求数据发送者重新提供公钥,直到攻击者不再截获公钥。这个过程中,这个第三方就是证书颁发机构(Certificate Authority,简称CA)。

然而攻击者现在仍然可以通过伪造证书来进行攻击,攻击者向数据发送者提供证明公钥和攻击者对应关系的证书,数据发送者就无法察觉这里面的异常了。为了证明证书不是伪造的,CA需要在证书上签名,也就是附上一段自己专属的额外信息,数据发送者看到来自CA的签名,就证明证书没有被篡改。这个来自CA的签名就是数字签名。然而数字签名也可能被篡改,所以,再来一次非对称加密!

Expand All @@ -57,3 +59,29 @@ HTTP协议又被称为“超文本传输协议”。它用一套固定不变的
但是就算是这种情况,也无法保证所有人都通过https协议传输了数据,那么软件在中间就有可能经过篡改。既然软件有可能被篡改,那么有没有更硬核的办法防止CA证书在传输过程中被篡改?CA于是动用自己的话语权说服了硬件制造商,让他们在自己的硬件里集成了CA证书。这样的CA证书位于诸如硬件安全模块(HSM)或可信平台模块(TPM)中。硬件是没法通过网络传输的,而且硬件在运输过程中受到真人的看管和现实中法律的保护,也就没有黑客在硬件的运输过程中篡改了。

然而,上面这些情况都是在基于CA有很大话语权的前提之下,现实中,如果CA有这么大的话语权,那么它就会非常大,非常权威,非常难以管理。现实中有些CA规模很小,他们无法说服开发者和硬件厂商为其集成证书。难道这些CA就没法干下去了吗?没关系,这些小CA的证书可以用其他大CA的证书来证明安全性,而大大小小CA的证书最终都要由几个十分有话语权的CA来证明真实性。这些十分有话语权的CA可以将他们的证书集成到软件或硬件中,而他们需要用自己的证书验证其他CA的证书,这样的CA就叫根CA。而根CA要验证大CA的证书,大CA又要验证小CA的证书,这样一整个验证的链条就叫证书链。证书链实现了小CA即使无法直接将证书集成到软硬件中,也可以通过委托根CA利用其权威证书来验证这个小CA的证书的真实性。有了证书链和上面的一整套加密流程,还有根CA的证书交至用户手中的这一通过其他方式确保根CA证书不被篡改的过程,我们的数据终于是可以完全保密地从数据发送者发送给数据接收者了。

然而,上面这些都是在根CA自己的私钥不被泄漏的前提下进行的。前面我们提到,为了确保大大小小CA的证书的真实性,根CA需要自己生成密钥对,然后将其证书通过物理方式基于https传输给用户。在这个过程中,攻击者由于无法伪造根CA的证书,就无法篡改被根CA证书证明的普通CA的证书。可是一旦根CA的私钥泄露,攻击者就可以通过根CA的私钥为自己伪造的普通CA的证书签名,并且数据接收者即使拥有未经篡改的根CA证书,也会将被篡改的普通证书验证为未篡改,因为被篡改的普通证书也是被根CA的私钥加密的,导致了它可以被用户手中的根CA证书证明为未加密。为了及时遏制根CA私钥泄露的安全隐患,根CA一旦发现私钥泄露,他会立即吊销对应的证书,并在整个网络上发布证书被吊销的公告。各种软件和网站程序都会高度关注这种公告,并且避免采用已经被吊销的证书来验证。

还记得我们刚才提到,数据接收者需要提供自己的身份和公钥给CA,才能证明自己和公钥的对应关系吗?你应该已经知道,在网络上,电脑拥有自己的地址,这个地址就是IP地址。这个IP地址将被作为电脑的身份发送给CA,用于和公钥形成绑定。然而,如果电脑的IP地址变了,证书就要重新申请,而我们还有一种技术用于让用户在电脑IP地址发生变化的情况下仍然能访问指定电脑:域名。这样,只要用域名去证明自己的身份,即使数据发送者的IP地址会变化,数据发送者也不需要重新申请证书。这也是SSL证书需要绑定到域名上的原因。但是电脑中了DNS污染的话,攻击者仍然是可以进行攻击的,而且这就超出HTTPS本身的能力范围了。为了防范DNS污染,可以采用配置DOH等手段,但是这已经超出了本文的讨论范围,让我们回到HTTPS本身吧。

证书需要CA机构的颁发和认证,CA机构的运行是需要费用的,所以CA会对申请SSL证书收取费用。资本太坏了,催我们升级HTTPS,然后还要在必经之路SSL证书上收钱,这不就是圈我们的钱吗?社区中有人站了出来,他们之中的代表是Let's Encrypt,以他们为首的一些CA并不对SSL证书收取费用,而是通过用高级证书的利润倒贴免费证书的成本,或者让社区出力的方式来为免费SSL证书提供服务。通过向他们申请免费的SSL证书,像我们这种需求量不大的个人用户或小团队也可以为自己的网站升级HTTPS,提升他们用户的信任度和体验,为建设安全的互联网添砖加瓦。

## 防止SSL证书被滥用——DNS-01挑战和HTTP-01挑战

SSL证书确实是确保了网站通信的安全性,但是这些都是确立在网站确实为申请者所有的前提之下的。如果申请者为不属于自己的网站或域名申请了SSL证书,那么申请者白花钱申请、申请者自己的网站加密失败或CA签发无效证书造成损失都是小事,一旦错误申请了SSL证书对应网站是真实存在的,申请者就可以向CA表示网站的域名是申请者所有而不是网站所有,这样一来就乱套了,申请者就可以随便插入客户端与真正网站的连接,发起中间人攻击。

为了防止这种现象发生,申请和续期证书时,CA需要进行一次验证,确保申请者确实拥有被申请了证书的网站。这个验证一般有两种:DNS-01挑战和HTTP-01挑战。

### DNS-01挑战

1. CA的服务器会向网站服务器发起一个挑战,要求网站证明其对域名的控制权
2. 网站服务器接收到挑战后,从CA获取一个唯一的令牌
3. 网站服务器使用令牌和账户密钥生成一个特定的哈希值,并将其作为 TXT 记录的内容
4. 网站服务器需要在域名的 DNS 区域文件中创建一个 TXT 记录,并将生成的哈希值作为记录值
5. 将生成的 TXT 记录添加到域名。
6. 网站服务器通知CA服务器已经部署了 TXT 记录
7. CA服务器会查询对应的域名是否存在且内容与预期的哈希值匹配

通过操作域名的解析记录,申请者就成功地证明了他拥有对域名的所有权。

### HTTP-01挑战

0 comments on commit 303e9f7

Please sign in to comment.