HTTPS 的工作原理

2025-05-25

HTTPS 的工作原理

大多数人都熟悉http://网站 URL 开头的“S”。有些人可能注意到,任何包含登录表单或敏感信息的网站都会以https://“S”开头。“S”代表“安全”,而使其运行的算法既疯狂又奇妙。为了理解 HTTPS 为何如此神奇,我们来打个比方。

假设你召集了三位经验丰富的程序员:Janice、Natalia 和 Mario。这三个人从未见过面,也从未以任何方式交流过。你把他们安排在一个房间里,让他们坐成一排,Natalia 坐在中间。

[ Janice | Natalia | Mario ]
Enter fullscreen mode Exit fullscreen mode

然后你给他们一个挑战。就像这样:

  1. 你会给 Janice 一个她需要发送给 Mario 的秘密信息。
  2. 如果娜塔莉亚 (Natalia) 发现了秘密信息,她将获得奖品,但珍妮丝 (Janice) 和马里奥 (Mario) 将一无所获。
  3. 如果马里奥收到了秘密信息而娜塔莉亚却没有发现,那么马里奥和珍妮丝都会得到奖品,而娜塔莉亚将一无所获。
  4. 她们只能通过传递纸条来交流。娜塔莉亚可以读任何她想读的纸条。

这似乎是一个无法破解的难题。如果娜塔莉亚能读到他们之间传递的所有信息,那么珍妮丝和马里奥又该如何秘密交流呢?这和我们在网络上面临的问题是一样的。你的网络浏览器始终在与远程服务器通信,而它们之间可能从未进行过通信。任何通过互联网发送的消息都可能被第三方拦截和读取,那么我们如何才能保证这些消息的保密性,避免你的密码和银行账号被盗呢?答案是 HTTPS。

花点时间思考一下这个谜题。你可能会想到,如果珍妮丝和马里奥能够秘密交换一点点信息(一个数字),他们就能用这些信息来加密剩下的信息。他们可以使用数字代换密码(A = 1,B = 2,C = 3,等等),然后将每个数字与秘密数字一起代入一个等式中,这样就能更难猜测哪些数字对应哪些字母。娜塔莉亚可能知道这个等式,但如果她不知道秘密数字,她就无法逆转等式并解码信息。

这个想法叫做对称密钥算法,我们一直在用它!这是一种加密和解密秘密信息的好方法。

剩下的就是想办法交换秘密数字了。Janice 对素数有一些了解,并且知道该怎么做。

首先,Janice 选了两个素数,分别叫做pg。她把它们发给了 Mario;Natalia 看到也没关系。

var p = 23;
var g = 5;
Enter fullscreen mode Exit fullscreen mode

然后,Janice 选一个秘密数字,随便什么数字都可以。假设这个数字是 3。

var janiceSecret = 3;
Enter fullscreen mode Exit fullscreen mode

她创建了以下函数:

function computeExchange(g, secret, p) {
  var exchange = Math.pow(g, secret) % p;
  return exchange;
}
Enter fullscreen mode Exit fullscreen mode

因此,她将g计算的幂secret,除以p,然后返回除法的余数。

computeExchange(g, janiceSecret, p);
> 10
Enter fullscreen mode Exit fullscreen mode

答案是 10。Janice 将这个数字发送给了 Mario。

var numberFromJanice = 10;
Enter fullscreen mode Exit fullscreen mode

然后马里奥选择一个秘密数字,比如 8,并运行相同的功能。

var marioSecret = 8;
computeExchange(g, marioSecret, p);
> 16
Enter fullscreen mode Exit fullscreen mode

马里奥得到 16 并将该数字发送给珍妮丝。

var numberFromMario = 16;
Enter fullscreen mode Exit fullscreen mode

还剩一步。Janice 再次运行该函数,但g她没有使用 ,而是使用了 Mario 刚刚发给她的号码。

computeExchange(numberFromMario, janiceSecret, p);
> 2
Enter fullscreen mode Exit fullscreen mode

马里奥也做了同样的事情:他再次运行该功能,但g用珍妮丝发给他的号码替换。

computeExchange(numberFromJanice, marioSecret, p);
> 2
Enter fullscreen mode Exit fullscreen mode

他们俩都得到了数字 2!这是巧合吗?不,不是。事实上,这是数学上的必然结果。无论他们选择哪个素数作为pg,也无论他们选择什么作为秘密数字,最终都会得到相同的数字——不一定是 2。在这种情况下,他们会使用 2 作为秘密数字来编码和解码他们的消息。这被称为Diffie-Hellman 密钥交换。让我们选择一些不同的数字,再做一次:

function computeExchange(g, secret, p) {
  var exchange = Math.pow(g, secret) % p;
  return exchange;
}

var p = 29;
var g = 7;
console.log('p and g are:', p, g)

var janiceSecret = 8;
var marioSecret = 5;

var numberFromJanice = computeExchange(g, janiceSecret, p);
console.log('Janice sends Mario', numberFromJanice);
var numberFromMario = computeExchange(g, marioSecret, p);
console.log('Mario sends Janice', numberFromMario);

var janiceKey = computeExchange(numberFromMario, janiceSecret, p);
var marioKey = computeExchange(numberFromJanice, marioSecret, p);

console.log('Their shared key should match:', janiceKey, marioKey);
Enter fullscreen mode Exit fullscreen mode

(请注意,对于稍大的值,p不起作用因为 JavaScript 不能很好地处理大数字。它在 Python 中可以正常工作。)gjaniceSecretmarioSecret

janiceKeymarioKey值都是 16。这个数字非常特殊。它从未在纸条中交换过。Natalia 从未见过它。Natalia 无法逆转这个等式,因为她不知道 Janice 或 Mario 的秘密数字。她所能做的就是猜测他们的秘密数字是什么,并尝试根据该数字找出编码/解码密钥。对于像我们使用的这样的小数字,她可能可以做到这一点。但如果 Janice 和 Mario 的密钥是非常大的数字,例如 115 792 089 237 316 195 423 570 985 008 687 907 853 269 984 665 640 564 039 457 584 007 913 129 639 935(256 位数字),那么它就会变得非常困难。而且,在挑战结束、你失去耐心或有人老死之前,娜塔莉亚绝对不可能找出他们共享的密钥并解码消息。

这几乎就是每次连接到使用 HTTPS 的服务器时,浏览器都会执行的操作。这被称为“TLS 握手”。有人可能会嗅探互联网连接,从一开始就读取您的浏览器发送和接收的每条消息,并且在共享密钥确定后仍然无法解码您的消息。这很疯狂吧?

还缺少一块拼图。假设娜塔莉亚特别狡猾,想出了一个欺骗挑战的计划:每收到一条消息,她就用一条她秘密创建的不同消息替换掉它。这样,她就可以分别与珍妮丝和马里奥进行 TLS 握手,而他们两个都不会察觉。当马里奥发来消息时,她会使用她和他创建的共享密钥(但马里奥以为这是他和珍妮丝创建的)对其进行解码,然后使用她和珍妮丝创建的共享密钥(珍妮丝以为这是她和马里奥创建的)对其进行编码。这是一种中间人攻击

幸运的是,这个问题有解决办法。假设Janice和Mario特别有洞察力,他们预测到这种情况可能会发生。他们会在你开始挑战之前联系你,指出挑战可能会被作弊。为了防止这种情况发生,他们会在每张纸条上签名,并请你把它贴到每个人都能看到的地方。这样,他们就可以对发送的消息进行签名。除非Natalia知道如何快速伪造签名,否则他们可以通过比较每张纸条上的签名和公开可见的签名来判断消息的真实性。

计算机使用数字签名对消息进行签名,这其中涉及的数学魔法我在这里就不赘述了。简而言之,一方提供公钥、消息和签名,另一方使用数学方法证明消息与公钥匹配。在网络上,此公钥通常由可信来源(称为证书颁发机构)提供,并预装在您的操作系统或网络浏览器中。这样,您的计算机就可以使用其已有的信息来验证来自未知来源的消息的真实性,并确保它与目标服务器建立了安全通信。

这一切都是为了不让别人知道你在看哪些猫咪视频。我猜,还有你的信用卡号。

文章来源:https://dev.to/isaacdlyman/this-is-how-https-works-223d
PREV
使用 Prisma、Supabase 和 Shadcn 设置 Next.js 项目。
NEXT
改进代码的步骤