我们如何以安全的方式在两台服务器之间交换公钥?

信息安全 公钥基础设施 密钥交换
2021-08-22 13:50:08

我有两台带有一对 RSA 公钥和私钥的服务器。

我们还没有使用 CA 进行内部通信,因此我们需要在没有 CA 的情况下交换密钥。

我需要在两台服务器之间建立信任:我需要将公钥从第一台服务器复制到第二台服务器,并将公钥从第二台服务器复制到第一台服务器。

请注意,这不是 Diffie-Hellman 密钥交换(在“Diffie-Hellman 密钥交换”中用简单的英语解释得很好)。

最简单的方法是手动将公钥从一台服务器复制到另一台服务器。

另一个选项是使用以下本地流程:

  1. 在第一台服务器上生成一次性令牌
  2. 手动将令牌复制到第二台服务器
  3. 第一台服务器通过 API 访问第二台服务器。作为 API 身份验证的令牌。API 实现在服务器之间交换公钥

有什么改善流量的建议吗?

我们是否有一些最佳实践流程,因为本土流程通常不利于安全?

4个回答

这将意味着大量不必要的开销。我建议如下:

  • 由于您没有 CA 颁发的证书,因此请创建自己的 CA。即,创建一个自签名证书并将其添加到两台服务器上的密钥库中,以便您的证书是可信的。
  • 向每个服务器颁发证书并使用您自己的 CA 的私钥对其进行签名。
  • 让您的服务器在与其他服务器通信时使用他们的证书。

因此,您实际使用 PKI。

将来,当您从真实的(众所周知的)CA 获得证书时,您唯一需要做的就是用真实CA的(也是自签名的)证书替换您自己的自签名 CA 证书。

不,我认为解决方案不好。让我们来看看:

  1. 这可以
  2. 如果我们可以手动复制,为什么不直接复制公钥呢?
  3. 这是真正的问题。由于这是在不安全的连接上完成的,因此您无法确定第一台服务器实际上与第二台服务器通信。

您没有具体说明交换的工作原理,但使用令牌作为简单的 API 身份验证令牌不会阻止MITM攻击。

在两台服务器之间的通信中,攻击者可以:

  • 在第一台服务器发送令牌时拦截令牌,将其转发以进行身份​​验证并将假公钥发送到第二台服务器
  • 将假公钥发送到第一台服务器,而不是来自第二台服务器的真实公钥

或可视化:

A  ------ token ----->  E  -- authenticate with token --> B
A  <-- fake pkeyB ----  E  <------ real pkeyB ----------- B
A  --- real pkeyA --->  E  ------- fake pkeyA ----------> B

您似乎想要对称密钥加密,也许像Kerberos之类的东西。但是对于您描述的用例,手动复制密钥似乎最简单(或者不安全地交换它们并手动检查接收到的密钥指纹)。

在由不受信任的网络分隔的两台服务器之间建立初始信任的唯一方法必须涉及手动1步骤。这可以通过手动复制或通过在信任密钥之前手动比较密钥是否正确传输来实现。手动比较通常使用密钥指纹完成。也可以通过比较复制文件的安全哈希(如 SHA-256)来完成。

还有其他方法,但它们必须涉及在两台服务器之间传输一条信息,没有办法绕过它。可以用数学方法证明。在我看来,通过不受信任的连接复制密钥并手动比较指纹是最直接的方法,也是相当标准的。

请注意,对于服务器网络,您只需为每个添加到网络的服务器传输一个密钥,对于 N 个服务器的网络,总共需要 N - 1 次此类操作。如果您希望将服务器 X 添加到服务器 A、B 和 C 相互信任的密钥的网络中,您只需要在 X 和例如 A 之间建立初始信任。然后可以在 X 和 B 之间以及 X 和 C 之间建立信任通过密钥签名建立。


1此处使用手册一词是为了简单起见。本质上意味着一条信息必须通过可信通道从一方(服务器)发送到另一方。这个受信任的通道可能是操作员驾驶到服务器并在一张纸上写下密钥指纹,因为它可能是受信任的电缆连接。此外,要在公钥交换的上下文中信任连接,它只需要抵抗中间人攻击,或者换句话说,它需要保持消息的完整性。潜在的连接窃听不会损害这种信任,因为所有此类攻击者都可以学习到公钥。

如果您有权访问任何受信任的 HTTPS 服务器,请将每个服务器的公钥发布在其上,然后在服务器上下载。

如果您的 HTTPS 服务器配置正确,则任何中间人都无法更改公钥,并且服务器可以安全地下载所有其他服务器的公钥。如果成本是一个问题,Let's Encrypt 可让您免费创建面向公众的 SSL 证书。