OpenSSL和s_client - 为什么客户端需要私钥?

时间:2012-06-26 00:03:32

标签: ssl openssl ssl-certificate

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

这是什么阻止了我,我不明白:

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

请记住,我刚刚开始使用SSL,因此我对整个协议有了非常基本的了解。从我一直在阅读的内容来看,似乎服务器和客户端都需要双向SSL设置中的私钥。但是,我无法弄清楚如何在我的客户端上获取工作私钥(使用提供给我的客户端证书)。 如果有人能够了解客户证书私钥,我将非常感激,因为这让我头疼不已。

谢谢!

3 个答案:

答案 0 :(得分:48)

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

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

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

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

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

  

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

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

事实上,不是给出证书及其私钥,而是更好的做法是生成密钥对,创建证书请求(CSR),让CA从该CSR颁发证书(但没有它们)永远都知道你的私钥)。在这种情况下,您可能会保留您的私钥,并且您可以将其与您收到的证书一起使用。

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分:0)

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