【问题标题】:Validating a CAcert certificate in C#在 C# 中验证 CAcert 证书
【发布时间】:2009-09-28 20:03:12
【问题描述】:

我目前正在创建一个 C# 程序,它将通过 https 从我的服务器获取一些数据。有问题的服务器正在使用 CAcert 证书 (http://www.cacert.org/),我需要一种验证服务器证书的方法(检查主题以及它是否由 cacert 根证书签名)。

我想这样做,而不必将 CAcert 根作为受信任的 CA 导入 Windows 证书存储区,有些人可能不喜欢这样,而 AFAIK 需要管理员。

我目前使用的是 TcpClient 和 SslStream 而不是 WebRequest/WebResponse 类,因为有一天我可能会从使用 HTTP 转向使用我自己的协议,但如果使用 *request 类更容易完成任务,我会考虑使用他们。

【问题讨论】:

  • 用户还可以将 CAcert 根证书导入他的个人存储中,这不需要任何“额外”权限。导入到个人商店实际上是使用 Windows 时的默认设置。

标签: c# ssl certificate


【解决方案1】:

首先你要使用重载的 SslStream 构造函数:

SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback);

那么 RemoteCertificateValidationCallback 方法看起来像这样:

public bool IsValid(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
     ... you logic here ...
}

您只需要简单地遍历链并查看证书,直到找到您愿意通过验证公钥接受的证书:

        foreach(X509ChainElement e in chain.ChainElements)
            if( e.Certificate.Subject == "CN=XXX.xx" && e.Certificate.GetPublicKeyString() == "expected public key" )
                return true;

【讨论】:

  • 只有在证书存储中存在根证书时,您的解决方案才有效。幸运的是,我找到了一种将证书添加到商店的简单方法,检查其中的证书数量是否发生变化,如果是,则在连接完成后删除证书。谢谢你教我如何走链子:)
  • 不应该要求证书在根存储中。我在 SSL 隧道中使用它,并且两端都没有看到外国证书。当您从 RemoteCertificateValidationCallback 返回 true 时,您会绕过证书存储检查并说无论如何都允许。
  • 如果根证书不在存储中,则链仅包含 1 个元素,即我要连接的主机的证书。但是,如果我将根证书添加到存储中,则链包含两个元素,服务器证书和根证书。很抱歉之前的评论不清楚。
  • 哦,对了,你……对此感到抱歉。对于这类东西,我几乎坚持自签名。当您无论如何都不信任他们时,无需涉及第三方:)
猜你喜欢
  • 2017-10-16
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多