【问题标题】:How to proper validate SSL certificate with X509Certificate2 on Mono and multiple platforms如何在 Mono 和多个平台上使用 X509Certificate2 正确验证 SSL 证书
【发布时间】:2016-10-18 07:59:30
【问题描述】:

我必须在一个非浏览器应用程序中验证几个 SSL 证书,以便在 IOS、Android 和 Linux 上运行 HttpRequestswebsocket 连接。 当发生通过HTTPS 的连接时,我会收到一组X509Certificate2 对象,其中底部是服务器证书,最顶部的是根CA(希望如此)。例如,当我连接到 https://google.com 时,我收到 3 个 X509Certificate2 和以下 SubjectName.Name

  • 0:"CN=google.com, O=Google Inc, L=Mountain View, S=California, C=US"
  • 1:"CN=Google Internet Authority G2, O=Google Inc, C=US"
  • 2:"CN=GeoTrust Global CA, O=GeoTrust Inc., C=US"

我现在需要使用给定信息和以下验证来验证证书验证:

  • 信任链验证
  • 主机名验证
  • 证书吊销验证

我尝试过但不理解并失败了:

当我在每个证书上独立调用X509Certificate2.Verify() 方法时,它每次都返回false。我也不明白为什么它可以返回 false 之后的任何其他内容,因为验证是独立进行的。相反,就我理解的理论而言,应该检查完整的链,即所有证书。

然后我使用了X509Chain 类:

foreach (X509Certificate2 cert in allthreecerts)
    {
        X509Chain chain = new X509Chain();
        X509ChainPolicy chainPolicy = new X509ChainPolicy()
        {
            RevocationMode = X509RevocationMode.Offline,
            RevocationFlag = X509RevocationFlag.EntireChain
        };
        chain.ChainPolicy = chainPolicy;
        if (!chain.Build(cert))
        {
            foreach (X509ChainElement chainElement in chain.ChainElements)
            {
                foreach (X509ChainStatus chainStatus in chainElement.ChainElementStatus)
                {
                    Debug.WriteLine(chainStatus.StatusInformation);
                }
            }
        }
    }            

这将为每个证书打印出RevocationStatusUnknownOfflineRevocation

再次,我不明白为什么这应该起作用,因为每个证书都是独立构建的链。父证书不应该是子证书的问题全部到根 CA 吗?

我想我需要什么,但不知道怎么做。

为了验证证书吊销,所有客户端都需要提供证书吊销列表。我从哪里获得这样的列表以及在哪里加载它并告诉连锁店使用这个本地列表?

同样的问题是信任链验证,因为最后一个认证应该是根认证,并且必须是客户信任的根 CA 之一。因此,例如,我必须加载 Firefox 附带的所有根 CA,并检查根 CA 是否是其中之一?最好的方法是什么?

[更新] 我在 google.com 示例中复制粘贴错误,我粘贴了两个相同的证书主题名称。

【问题讨论】:

  • RevocationMode = X509RevocationMode.Offline -- 切换到Online。客户端必须具有本地 CRL/OCSP 缓存才能在脱机模式下成功验证吊销。
  • 这就是重点。我正在实施“客户”。那么我如何提供这样的 CRL。这就是我要问的问题。
  • CRL 是从在线资源中检索的。 CRL 位置在CRL Distribution Points 证书扩展中指定。或者在Authority Information Access 扩展的On-line Certificate Status Protocol 部分中。
  • 谢谢,.NET 中是否有任何帮助程序可以加载这样的 .crl 文件并搜索它以检查特定证书是否已被吊销?
  • 您可以使用充气城堡来解析 CRL。也许 Mono 也有一些东西,但我对 Mono 不是很熟悉。

标签: c# mono ssl-certificate x509certificate2


【解决方案1】:

当发生通过 HTTPS 的连接时,我会收到一组 X509Certificate2 对象,其中底部的对象是服务器证书,最顶部的对象是根 CA(希望如此)。

如果您确实从 SSL 服务器获得了 root ca 证书,那么 SSL 服务器配置不正确。它应该返回其服务器证书和除根 CA 证书之外的整个链。

当我对每个证书单独调用 X509Certificate2.Verify() 方法时,它每次都返回 false。

正如X509Certificate2.Verify方法This method builds a simple chain for the certificate and applies the base policy to that chain.documentation中所述,现在the base policy是什么我不知道。但是ChainPolicy 的默认值之一是RevocationMode = X509RevocationMode.Online。至于 Mono,这个方法的来源可以找到here。 X509Chain的Mono实现源码可以在here找到。

这会打印出每个证书的 RevocationStatusUnknown 和 OfflineRevocation。

当您指定 RevocationMode = X509RevocationMode.Offline 并且缓存中没有 CRL 或 OCSP 响应(可能)时,它还应该打印什么?

为了验证证书吊销,所有客户端都需要提供证书吊销列表。我从哪里获得这样的列表以及在哪里加载它并告诉连锁店使用这个本地列表?

链中的每个证书(除了根 ca 证书)都包含一个到 CRL 的链接(或多个链接)。 .NET 和很可能也是 Mono has 一个实现,它将在证书中找到指向 CRL 的链接,将下载它并检查证书是否未被吊销。

同样的问题是信任链验证,因为最后一个认证应该是根认证,并且必须是客户端信任的根 CA 之一。因此,例如,我必须加载 Firefox 附带的所有根 CA,并检查根 CA 是否是其中之一?最好的方法是什么?

不,RevocationFlag = X509RevocationFlag.EntireChain 会使用 mono 使用的某些商店为您执行此操作。我不知道它是否是 Firefox 商店,但在 Linux 上它有自己的商店,您可以从 Firefox 商店导入根 ca 证书。检查 ChainElements 并亲自查看它找到了哪些证书。

我建议您使用RevocationMode = X509RevocationMode.OnlineRevocationFlag = X509RevocationFlag.EntireChain 仅使用 SSL 服务器证书构建链(因为这将检查链中向上的所有证书)。我还会尝试将 X509Chain 的 ExtraStore 属性设置为您从 SSL 服务器获得的证书列表。在 Build 方法之后,我会检查 X509Chain 对象的 ChainStatus 属性,它是一个状态数组。我会选择所有未将X509ChainStatus.Status 设置为 NoError 的状态。如果会有任何这样的状态,我会抛出并记录每个 X509ChainStatus.Status 和 X509ChainStatus.StatusInformation

HTH

【讨论】:

  • 这是我不明白的部分。如果这只是链的一个证书,X509Certificate2.Verify如何构建完整的链?我设置了RevocationMode = X509RevocationMode.Online,它产生了完全相同的结果。 ExtraStore 属性有一个私有设置器,所以我无法设置它。但是,如果 CRL 下载/检查以及如果使用 CA 存储,那么它不应该已经工作了吗(使用 RevocationMode = X509RevocationMode.Online 时)?
  • X509Chain 的 ChainStatus 属性始终包含 3 个元素。 "PartialChain","RevocationStatusUnknown" 和 "OfflineRevocation" 即使是RevocationMode = X509RevocationMode.Online
  • @zlZimon X509Certificate2.Verify 使用一些 Mono 证书存储来查找证书以构建链。 SSL 服务器确实(不应该)发送根 ca 证书,因此您作为客户端必须针对您信任的根 ca 证书的证书存储构建链。从this site 尝试 tlstest。同样在此页面上,您会找到Note that a default installation of Mono doesn’t trust anyone!,因此您需要使用certmgr.exemozroots.exe 手动填写受信任的根证书。
  • 不幸的是,我必须使用非常旧的 Mono 版本 (2.6),所以只有 mozroots.exe 可以工作。不幸的是,我在 Mac 上....
  • 好的,我现在安装了一个带有 Windows 的 VM 并运行 mozroots.exe --sync --import。我收到以下错误:Downloading from 'http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1'... No certificates were found. 当我将链接粘贴到浏览器中时,我从 mozilla 收到服务中断...那么我在哪里可以获得另一个可以使用的链接?
猜你喜欢
  • 2017-04-28
  • 2015-04-12
  • 2021-12-18
  • 2019-10-31
  • 1970-01-01
  • 2019-12-26
  • 2020-01-05
  • 2011-04-10
  • 1970-01-01
相关资源
最近更新 更多