【问题标题】:OpenSSL and s_client - why is a private key required from the client?OpenSSL 和 s_client - 为什么客户端需要私钥?
【发布时间】:2021-05-15 14:18:05
【问题描述】:

我需要在 .NET/WCF 应用程序和第三方 Web 服务器之间设置 2 路 SSL 通信通道。现在我正在尝试与主机成功握手,以验证所有元素是否设置正确(客户端证书、服务器证书颁发机构、网络通信......)。我正在使用 openSSL 命令行工具尝试并使用 s_client 命令验证这一点。

以下是阻止我的原因,以及我不明白的原因:

  • 无论我做什么,openSSL 都希望为 客户证书
  • 客户端证书是由第三方提供给我的,但它 不包含任何私钥
  • 如果我只是使用 openSSL 生成我自己的私钥文件,我会得到 键值不匹配错误

请记住,我刚刚开始接触 SSL,所以我对整个协议有一个非常基本的了解。从我一直在阅读的内容来看,似乎服务器和客户端都需要采用 2 路 SSL 设置的私钥。但是,我不知道如何在我的客户端上获得一个有效的私钥(使用给我的客户端证书)。 如果有人能对客户端证书私钥有所了解,我将不胜感激,因为这让我很头疼。

【问题讨论】:

  • 如果有的话,唯一应该给你的就是服务器证书。没有其他人可以给你一个客户端证书:你必须从你自己的私钥开始自己构建它。可能给你的人也不明白。
  • 这样说,确实更有意义。而且我会确认我有一种感觉,我周围的人似乎不太了解整个 SSL 事情。猜猜这取决于我提高这个主题的标准(这是我在这里想要完成的)。

标签: ssl openssl ssl-certificate


【解决方案1】:

证书本身只是公开的信息。将公钥证书与其包含的名称相关联的事实是,任何对该名称具有合法控制权的人(例如您的姓名或您的服务器的名称)也拥有它的私钥。

证书用于通过挑战远程方执行只能使用相应私钥才能完成的操作来证明远程方的身份:签署某事(可以使用公钥验证)或解密某事是用公钥加密的。 (两者都可能发生在 SSL/TLS 握手中,具体取决于密码套件。)

在 SSL/TLS 握手期间,服务器发送其证书(明文)并向客户端证明其拥有相应的私钥 using an authenticated key exchange

在您的情况下,您还希望使用客户端证书身份验证。在握手期间发送客户端证书是不够的:客户端还必须证明它拥有私钥。否则,任何收到该证书的人都可以克隆它。使用证书的目的是防止任何克隆,这样您就不必显示自己的秘密(私钥)。

更具体地说,客户端必须在 TLS 握手的Certificate Verify 消息中对握手消息进行签名,以便服务器可以根据客户端证书中发送的公钥对其进行验证。如果没有这一步,将不会发生客户端证书身份验证

客户端证书是由第三方提供给我的,但确实如此 不包含任何私钥

在没有私钥的情况下为您提供证书似乎有点毫无意义,除非您事先已在您身边生成证书请求(在这种情况下您将拥有私钥)。

确实,与其获得证书及其私钥,不如生成密钥对、创建证书请求 (CSR) 并让您的 CA 从该 CSR 颁发证书(但没有它们知道你的私钥)。在这种情况下,您应该保留您的私钥,并且您可以将它与您将收到的证书一起使用。

【讨论】:

  • 所以基本上我在这里有 2 个选择:1 - 如果他们有证书的私钥(如果他们有的话,他们可能会这样做),但这根本不是标准做法或 2 -使用openSSL(例如)生成密钥+ CSR并给他们那个CSR。然后,CSR 应该拥有生成与我的私钥对应的客户端证书所需的信息?
  • 是的。 (请注意,除了 OpenSSL 之外,还有其他方法可以生成密钥对并申请证书,特别是有一些基于浏览器的 CA,其中密钥是在浏览器中生成的,并且可以导出。)
  • 现在搞定了整个私钥。仍然面临其他问题,但基于不同的理由,所以这回答了我的问题。非常感谢您花时间以如此有用的方式解释这一点。
【解决方案2】:

这是一个有趣的问题。我在配置 LDAPS 时对 TLS 相关的错误感到困惑,我在这里学习。

  • 名称,“公钥”和“私钥”听起来像是一种单向操作,但它可以双向工作,任何由一个密钥加密并由另一个密钥解密的东西 - 只是一个密钥被公开
  • 信息 = 公开可用的数据,完整性未知 - 它可能被第 3 方篡改
  • 签名 = 由私钥加密的信息,伴随信息
  • 验证签名 = 使用公钥解密签名并取回信息,从而证明“创建签名的人知道私钥”,或者,信息在签名后保持不变
    • 也就是说,除非私钥被盗
  • 证书 = 信息 + 签名 + 公钥 + 私钥
    • 信息 = 肉
    • 签名 = 验证信息的完整性
    • 公钥 = 验证其他证书,参见证书链
    • 私钥 = 不包含在证书本身中,但应由证书所有者保存,可用于签署其他证书
  • 证书颁发机构 (CA) = 持有公钥/私钥对并创建证书的任何人
    • CA 身份在证书信息中指明
  • 证书链 = 使用母证书上的公钥来验证子证书上的签名,以确保子证书由母 CA 创建和签名
    • 还有妈妈由奶奶创建和签名,等等
  • 根 CA = 根 CA 是您无条件信任的 CA
    • 因为它们的证书(根证书)已作为信任源预加载在您的浏览器或操作系统中
    • 还因为他们的证书是自签名的,其​​签名是使用自己的私钥创建的,并由自己的公钥验证
    • 这可能会令人困惑,但将其视为基于证书的加密的起源 - 只有当人们发现依赖少数根 CA 来创建和签署无数证书是不安全的(私钥可能会被盗)并且不可能(证书需求迅速增长),他们提出了证书链的想法
    • 根 CA 仅为某些中间 CA 创建和签署证书,因此私钥不会经常使用并且更安全
    • 中间 CA 可以创建和签署数百万个证书,并在已知私钥泄露时撤销其证书
    • 这就是您不常看到根密钥仪式的原因,这表明私钥对于根证书的重要性:私钥使用得越少,暴露的可能性就越小
  • 自签名根证书 = 几乎与根证书相同 - 只是创建者不会信任任何人
  • TLS 握手 = 服务器发送证书,客户端验证与证书链相反,验证后,安全地交换“密码”
    • “密码”随后用于使用对称加密对实际数据传输进行加密
    • 非对称加密不用于实际数据,因为它需要强大的计算能力
  • 客户端证书身份验证 = 除了先前验证服务器的过程之外,服务器还要求客户端提供有效证书,以及先前握手消息的签名
    • 签名是使用证书的私钥创建的,可以通过证书上的公钥进行验证
    • 这证明了证书的所有权
    • 这通常用于限制对已知个人客户端的访问
    • 使用证书意味着不会发生中间人攻击或重放攻击
    • 这在金融或物联网中很常见
    • 这也被 LDAPS 使用,当我在本地密钥库中有一个有效的证书但它没有附带它的私钥时,它会导致神秘的错误消息

...所以,就openssl而言,当您使用-cert时,您表示客户端证书身份验证,您将需要-key指定相应的私钥。

但是,对于很多Web场景,即使服务器的证书是由自制的CA签署的,只需将自制的CA添加到truststore或keychain,就可以验证服务器证书。这是通过使用-CAfile 完成的。

【讨论】:

    【解决方案3】:

    底线.. 如果您要发送客户端证书,那么您将需要客户端证书的私钥来加密 pre-master secret

    【讨论】:

      猜你喜欢
      • 2018-04-03
      • 2017-01-17
      • 1970-01-01
      • 2018-11-28
      • 2017-12-23
      • 2011-08-20
      • 2019-10-18
      • 1970-01-01
      • 2011-07-19
      相关资源
      最近更新 更多