发送客户端证书如何不将客户端暴露给模拟

How does sending client certificate not expose the client to impersonation

好的,为了方便交流,我将参考这张图片

好的,所以服务器会发送一个 public 密钥,客户端使用它来加密自己的证书信息以发送回服务器。我不明白的是为什么攻击者无法拦截来自步骤 4 的数据包,然后使用它发送到服务器以冒充客户端。他们不必知道里面的信息或解密它。如果攻击者获得并保存了该数据包,他们就可以在服务器请求客户端证书时将这些确切的字节发送到服务器。我不确定这种加密方法如何防止这种类型的攻击。话又说回来,在套接字级加密方面我完全是菜鸟,所以我可能会遗漏一些重要的东西。谢谢!

事情比那更复杂,这张图片有一些缺陷,混合了本地存储和交换的东西。

查看 https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake,特别是“客户端验证的 TLS 握手”案例。

总结:

  • 有时服务器会要求客户端发送证书(这并不总是需要的,因此服务器会发送一条特定的消息来请求它,CertificateRequest
  • 客户端随后回复 Certificate 消息,其中包含其证书
  • 在那个阶段,服务器已经可以根据所提供的证书来决定是否要更进一步;确实在那个阶段其他人也可以发送相同的证书,因为它是 public。但是接下来解释了为什么它不能在 TLS 握手
  • 中进一步工作
  • 在来自服务器的包含各种加密数据的 ClientKeyExchange 消息之后,这些数据将在以后真正加密应用程序数据的交换,
  • 客户端发送 CertificateVerify 消息,这是在之前握手中的 TLS 消息交换上计算的签名,使用与客户端证书关联的 private 密钥完成
  • 收到此消息的服务器可以仔细检查它是否正在与真正的客户端通话,因为通过尝试使用客户端 public 密钥(包含在证书中)验证签名,它会知道远程方是否是否确实有正确的关联私钥。

所以攻击者不能通过窃取证书来冒充客户端(在另一种情况下存在相同类型的保护,以验证服务器),当然只要私钥保持私密。如果私钥被盗,则上述所有方法都将失败。

此时没有必要了解加密签名的所有细节,只是系统的设计方式是,由其中一个密钥加密的所有内容只能由另一个密钥解密:如果有人加密数据与它的私钥,然后任何人都可以用它的 public 密钥(根据定义,public 解密它;然后你通常会遇到传播它的问题,但这里不是 public 密钥包含在握手之前交换的证书中);这当然对机密性毫无用处(任何人都可以看到加密的内容),但它是身份验证的基础,因为如果解密有效,则意味着发件人拥有与您用来解密的 public 私钥相关联的私钥。

请注意,对于刚刚作为新标准发布的 TLS 1.3,TLS 交换中消息的数量和性质略有变化,但上述加密保证(使用私钥签署某些内容,以便远程方可以用关联的 public 键仔细检查)仍然成立。

除了 回答之外,在 mTLS 期间还会比较时间戳。如果传入时间戳超出某个限制,会话将被放弃,因此您截获的数据包将变得无用。

https://en.wikipedia.org/wiki/Mutual_authentication#Defenses