C#从网站下载所有https证书 [英] C# Download all https certificates from a website

查看:327
本文介绍了C#从网站下载所有https证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将所有证书从URL保存到磁盘。例如,



使用Firefox,我可以将它们全部导出,然后保存到磁盘中。



所以我想在C#中做到这一点。
我开始使用以下代码获取证书。

  ///< summary> 
///从URL获取证书并将其写入路径
///< / summary>
///< param name = _ URL>带有certficate< / param>的网站的URL;
///< param name = _ path>您想存储证书的路径< / param>
私有静态无效SaveCertificate(String _URL,String _path)
{
try
{
HttpWebRequest request =(HttpWebRequest)WebRequest.Create(_URL);
request.AllowAutoRedirect = false;

HttpWebResponse响应=(HttpWebResponse)request.GetResponse();
response.Close();

X509Certificate2 cert =新的X509Certificate2(request.ServicePoint.Certificate);

File.WriteAllText(_path,ExportToPEM(cert));
}
捕获(例外)
{
}
}

///< summary>
///将证书导出为PEM格式字符串
///< / summary>
///< param name = _ cert>要导出的证书< / param>
///< returns> PEM编码的字符串< / returns>
公共静态字符串ExportToPEM(X509Certificate2 _cert)
{
StringBuilder builder = new StringBuilder();

试试
{
builder.AppendLine( ----- BEGIN CERTIFICATE -----);
builder.AppendLine(Convert.ToBase64String(_cert.Export(X509ContentType.Cert),Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine( ----- END CERTIFICATE -----);

}
捕获(例外)
{
}

return builder.ToString();
}

此代码的问题是,我只得到一张证书,证书只有三份。 (我得到的证书是firefox截图中的标记证书)



我还尝试了以下方法 SO Question ,但它对我没有用。



我的问题是,如何从URL获取所有证书?

解决方案

获得证书链的一种方法是实现 ServerCertificateValidationCallback 在您的请求中。



该函数接受以下参数:



(对象发送者,X509证书,X509链,SslPolicyErrors sslPolicyErrors)



通常用于验证证书和链,但是在这种情况下,我们只是使用它来访问证书链。 确实感觉很像黑客,但是应该可以。我已经根据您发布的代码实施了概念验证。代码将证书输出到控制台窗口。

  public static void Main(string [] args)
{
SaveCertificate( https://www.google.de,);
}
///< summary>
///从URL获取证书并将其写入路径
///< / summary>
///< param name = _ URL>带有certficate< / param>的网站的URL;
///< param name = _ path>您想存储证书的路径< / param>
私有静态无效SaveCertificate(字符串url,字符串路径)
{

var request =(HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
request.ServerCertificateValidationCallback = ServerCertificateValidationCallback;

HttpWebResponse响应=(HttpWebResponse)request.GetResponse();
response.Close();
Console.ReadLine();

}

私有静态bool ServerCertificateValidationCallback(对象发送者,X509证书,X509Chain链,SslPolicyErrors sslPolicyErrors)
{
foreach(链中的var cer)。 ChainElements)
{
Console.WriteLine(cer.Certificate.FriendlyName);
Console.WriteLine(ExportToPem(cer.Certificate));
}

返回true;
}

///< summary>
///将证书导出为PEM格式字符串
///< / summary>
///< param name = _ cert>要导出的证书< / param>
///< returns> PEM编码的字符串< / returns>
公共静态字符串ExportToPem(X509Certificate2 cert)
{
StringBuilder builder = new StringBuilder();

试试
{
builder.AppendLine( ----- BEGIN CERTIFICATE -----);
builder.AppendLine(Convert.ToBase64String(cert.Export(X509ContentType.Cert),Base64FormattingOptions.InsertLineBreaks));
builder.AppendLine( ----- END CERTIFICATE -----);

}
捕获(例外)
{
}

return builder.ToString();
}


I want to save all certificates from a URL to disk. So for example https://www.google.de

If I browse this page with Firefox, I can see three certificates.

With Firefox I can export them all, and save them to disk.

So I want to do that in C#. I started getting the certificates with the following code..

    /// <summary>
    /// Get and write certificate from URL into file in path
    /// </summary>
    /// <param name="_URL">URL of website with certficate</param>
    /// <param name="_path">Path where you want to store certificate</param>
    private static void SaveCertificate(String _URL, String _path)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_URL);
            request.AllowAutoRedirect = false;

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            response.Close();

            X509Certificate2 cert = new X509Certificate2(request.ServicePoint.Certificate);

            File.WriteAllText(_path, ExportToPEM(cert));
        }
        catch (Exception)
        {
        }
    }

    /// <summary>
    /// Export a certificate to a PEM format string
    /// </summary>
    /// <param name="_cert">The certificate to export</param>
    /// <returns>A PEM encoded string</returns>
    public static string ExportToPEM(X509Certificate2 _cert)
    {
        StringBuilder builder = new StringBuilder();

        try
        {
            builder.AppendLine("-----BEGIN CERTIFICATE-----");
            builder.AppendLine(Convert.ToBase64String(_cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
            builder.AppendLine("-----END CERTIFICATE-----");

        }
        catch (Exception)
        {
        }

        return builder.ToString();
    }

The problem with this code is, I just get one certificate exept three. (the certificate I get is the marked certificate in the screenshot from firefox)

I also tryed the solution from here SO Question but it didnt work for me.

My question is, how can I get all certificates from a URL?

解决方案

One way you can get the certificate chain is by implementing a ServerCertificateValidationCallback on your request.

It's a function that accepts the parameters:

(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)

This is normally used to validate the certificate and chain, but in this case we're just using it to get access to the certificate chain. It does feel a lot like a hack but it should work. I've implemented an proof of concept based on your posted code. The code outputs the certs to the console window.

   public static void Main(string[] args)
    {
        SaveCertificate("https://www.google.de", "");
    }
    /// <summary>
    /// Get and write certificate from URL into file in path
    /// </summary>
    /// <param name="_URL">URL of website with certficate</param>
    /// <param name="_path">Path where you want to store certificate</param>
    private static void SaveCertificate(string url, string path)
    {

            var request = (HttpWebRequest)WebRequest.Create(url);
            request.AllowAutoRedirect = false;
            request.ServerCertificateValidationCallback = ServerCertificateValidationCallback;

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            response.Close();
            Console.ReadLine();

    }

    private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        foreach (var cer in chain.ChainElements)
        {
            Console.WriteLine(cer.Certificate.FriendlyName);
            Console.WriteLine(ExportToPem(cer.Certificate));
        }

        return true;
    }

    /// <summary>
    /// Export a certificate to a PEM format string
    /// </summary>
    /// <param name="_cert">The certificate to export</param>
    /// <returns>A PEM encoded string</returns>
    public static string ExportToPem(X509Certificate2 cert)
    {
        StringBuilder builder = new StringBuilder();

        try
        {
            builder.AppendLine("-----BEGIN CERTIFICATE-----");
            builder.AppendLine(Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
            builder.AppendLine("-----END CERTIFICATE-----");

        }
        catch (Exception)
        {
        }

        return builder.ToString();
    }

这篇关于C#从网站下载所有https证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆