为什么 Tor 出口节点可以解密数据,而入口节点却不能?

信息安全 加密 保密
2021-09-02 22:26:41

Me -> Node A -> Node B -> Node C -> destination

Tor 上的文档总是声明只有出口节点 C 可以看到纯文本数据。如果我不直接与节点 C 交谈,这怎么可能?

如果我有一些纯文本数据,并且想将其加密发送到节点 A,我通常会进行 Diffie-Hellman 密钥交换,然后将数据发送过来。但是通过该方案,节点 A 可以解密数据。

如果节点 C 以某种方式与我共享它的公钥,那么节点 B 或节点 A 的 MITM 不能是密钥吗?

Tor 究竟是如何管理其 PKI 的?哪些密钥用于在哪里加密数据?

3个回答

Tor 使用一种称为洋葱路由的路由方法。就像洋葱一样,每条消息(洋葱的核心)都覆盖着多层加密。 属性:维基百科图片归属地

您的消息在离开您的设备之前会经过多次加密。节点 A 只能解密(剥离)层 A,在该层下它会看到下一个节点的地址。数据包到达下一个节点后,只能解密(剥离)B层,以此类推。对于每一层,您都使用相应节点的公钥,因此只有该确切节点可以使用自己的私钥解密该层。

当消息到达出口节点时,所有层都已解密并且消息现在是明文(如果您在 SSL 下与服务器通信,它也可以被加密)。

TOR 使用洋葱路由的原理。假设涉及 3 个 TOR 节点 A、B 和 C(由客户端随机选择),消息为 m。我们假设这些节点对应的公钥是 Pa、Pb 和 Pc。

消息由客户端重复加密,从出口节点的公钥(Pc)开始,然后是 Pb,最后是 Pa(洋葱路由)。

Data received by node A: Pa(Pb(Pc(m))) 
Data received by node B: Pb(Pc(m)) 
Data received by node C: Pc(m)  

数据在每个节点使用其对应的私钥解密。解密后,每个节点都会获得一些关于将剩余数据转发到何处的纯文本信息。这确保没有单个节点知道整个路径每个节点只知道前一个节点和下一个节点。

ps 在我们的社区博客中有一篇关于 TOR 的非常好的文章,但不知何故我找不到它。如果有人找到链接,请将其添加到答案中。

这里有两个不同的问题:
1-我们如何发送数据以及节点如何解密每一层加密?
2-我们如何从出口节点获取数据?
关于第一个问题,我可以说没有用于将数据发送到目的地的公钥加密,而是共享秘密。在此之前,您应该对DH有足够的了解
DH步骤:

  1. Alice 和 Bob 就有限循环群 G 和 G 中的生成元素 g 达成一致。(这通常在协议的其余部分之前很久就完成;假设所有攻击者都知道 g。)我们将乘法写出群 G。
  2. Alice 选择一个随机自然数 a 并将 g^a 发送给 Bob。
  3. Bob 选择一个随机自然数 b 并将 g^b 发送给 Alice。
  4. Alice 计算 (g^b)^a。
  5. Bob 计算 (g^a)^b。

在这些步骤之后,Alice 和 Bob 有了一个 Shared Secret 并且没有人知道这个 Shared Secret。

托尔步骤:

  1. OP(洋葱代理或源)将 g^a 发送到 Node1(洋葱路由器)。(但由 Node1 的公钥加密)
  2. Node1 使用私钥解密数据,然后将 g^b 发送给 OP。(以明文形式。因为如果 OR 知道 OP 的公钥,那么隐私在哪里!!)。
  3. 现在 OP 和 Node1 有一个共享密钥。[例如:SS1 = OP & Node1 = 2]。
  4. OP 将 g^a 发送到 Node1,Node1 应将其发送到 Node2。('a' 是一个新的随机数)
    OP 使用 Node2 公钥加密 g^a,并使用加密数据(en(g^a) 和 Node2 地址) SS1。
  5. Node1用SS1解密数据并得到Node2地址,并将剩余的加密g^a发送给Node2。
  6. Node2用她的私钥解密数据,然后再次将g^b发送给Node1。(明文)
  7. Node1 用 SS1 加密 g^b 并发送给 OP。
  8. OP 使用 SS1 解密数据。
  9. 现在 OP 和 Node2 有一个 Node1 不知道的共享密钥。[例如:SS2 = OP & Node2 = 5]。

这将一直持续到电路完成。现在 OP 可以通过具有(SS1,SS2,...)的节点发送目的地请求。最后发送请求应该是这样的:

OP 到 Node1 => encryptSS1(发送到 Node2,encryptSS2(发送到目的地,“hello server”))

关于第二个问题接收响应应该是这样的:

  1. 目的地到Node2 =>“你好客户端”
  2. Node2 到 Node1 => encryptSS2("hello client")
  3. Node1 到 OP => encryptSS1(encryptSS2("hello client"))
  4. 操作解密SS1(解密SS2(数据))。

看看这个页面上的图片:
洋葱路由 - pikneek