【问题标题】:Retrieving certificate using OpenSSL .Net使用 OpenSSL .Net 检索证书
【发布时间】:2012-05-10 14:10:31
【问题描述】:

我想使用 OpenSSL .Net 包装器将证书从远程服务器检索到我的 C# 代码。本质上,我想复制

openssl s_client -connect 192.168.254.13:636 -showcerts

.. 最终将结果带入 X509Certificate。这可能吗,如果可以的话,谁能指出我正确的方向?

【问题讨论】:

    标签: c# .net openssl


    【解决方案1】:

    我认为这个问题有两个部分:

    1. 如何检索服务器的证书
    2. 如何检索证书链

    要重新获取服务器的证书,请使用 SslStream,其方法类似于 .NET 自己的 SslStream

    var serverName = "...;
    var client = new TcpClient(serverName, 443);            
    
    // Create an SSL stream that will close the client's stream.
    using (var sslStream = new SslStream(client.GetStream(),true))
    {
        sslStream.AuthenticateAsClient(serverName);                
        var serverCertificate = sslStream.RemoteCertificate;
     }
    

    OpenSSL.Net 似乎无法检索证书链。 -showcerts 参数使用在 OpenSSL.NET 中未实现的 SSL_get_peer_cert_chain 函数。

    如果您不介意混合使用 OpenSSL.Net 和内置 .NET 类,您可以将 OpenSSL.Net 证书转换为 .NET 证书并使用 .NET 的 X509Chain.Build 检索链。您可以使用 .NET 证书的 RawData 属性将 .NET 证书转换回 OpenSSL.NET 证书。

    var managedCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(serverCertificate.DER);
    var chain = new System.Security.Cryptography.X509Certificates.X509Chain();
    chain.Build(managedCert);
    
    
    foreach (var element in chain.ChainElements)
    {
        var raw = element.Certificate.RawData;
        using (var bio = new BIO(raw))
        {
            var oc = OpenSSL.X509.X509Certificate.FromDER(bio);
        }
    }
    

    也许您可以使用 .NET 的 SslStream 和 X509Certificate2 对象来使用原始证书数据执行您想要的操作,而无需使用 OpenSSL.Net。

    【讨论】:

    • Use a particular CA for a SSL connection 将避开 Windows 证书存储中的 CA Zoo 进行验证。但是,您必须提供一个受信任的 CA 来验证链。如果您知道颁发证书的 CA,那么最好只使用一个 CA,而不是数百个可用的 CA。
    • @jww 你的提议是一个已经被多次利用的安全风险——最近一次是心脏出血漏洞的结果。 CA 证书过去曾被泄露和撤销。通过使用本地存储作为 CA,您无法验证证书或知道证书已被吊销。没有“CA Zoo”,这只是证书的工作方式。
    • @Panagiotis - Peter Guttman 在他的Engineering Security 书中谈到了加州动物园等。这是一本很棒的书,我建议你浏览一下。特别是关于 PKI 的第 1 章和第 6 章。我不记得我上一次依赖 CA Zoo 是什么时候了。 CA Zoo 为我们带来了 DigiNotar 为 Google、Hotmail、Yahoo 等和接受这些证书的愚蠢客户颁发证书。这是一个不可接受且可预防的失败。
    【解决方案2】:

    尝试使用 ServicePointManager.ServerCertificateValidationCallback。这将使用服务器的 X509 证书等调用

    http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx

    【讨论】:

    • 恐怕对我没有好处 - 我希望使用 OpenSSL 从非 HTTPS 服务中检索证书。
    【解决方案3】:

    为了创建与 s_client 相同的功能,您可能必须看一下 s_client 的代码。

    你可以在openssl-X.Y.Z.tar.gz/apps/s_client.c里面找到s_client

    可能 PEM_write_bio_X509 会“打印” X509Certificate:

    if (c_showcerts)
        PEM_write_bio_X509(bio,sk_X509_value(sk,i));
    }
    

    但也有连接部分...

    ftp://ftp.openssl.org/source/openssl-1.0.1.tar.gz

    【讨论】:

    • 我希望有一些使用 OpenSSL.net 的“简单”方法,但它似乎不是:(
    【解决方案4】:

    要获取 CRL,首先检查证书及其颁发证书,以查找包含 URI GeneralName 的 cRLDistributionPoints 扩展。此扩展在 RFC 3280 中定义,它为 CA 指定了一种方式来传达与用于颁发另一个证书的证书相对应的 CRL 的位置。不幸的是,这个扩展被定义为可选的,大多数根 CA 不使用它。

    【讨论】:

    • 我不确定这与我原来的问题有什么关系?我对 CRL 不感兴趣,这是我想要获取的“原始”证书...
    猜你喜欢
    • 2013-09-22
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    相关资源
    最近更新 更多