C# 请求被中止:无法创建 SSL/TLS 安全通道

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10822509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:24:38  来源:igfitidea点击:

The request was aborted: Could not create SSL/TLS secure channel

c#asp.netsslhttpwebrequest

提问by Joseph Anderson

My customer has informed my of issues with their SSL and Internet Explorer. They said they get trust issues when accessing the URL.

我的客户已将其 SSL 和 Internet Explorer 的问题告知我。他们说他们在访问 URL 时遇到了信任问题。

I am accessing JSON through HTTPS. The website sits on one server and I am using the console app on my local machine. I am trying to bypass the SSL Cert, however, my code still fails.

我正在通过 HTTPS 访问 JSON。该网站位于一台服务器上,我在本地计算机上使用控制台应用程序。我试图绕过 SSL 证书,但是,我的代码仍然失败。

Can I alter HttpWebRequest to fix this problem?

我可以改变 HttpWebRequest 来解决这个问题吗?

I get this error using this code:

我使用此代码收到此错误:

    // You must change the URL to point to your Web server.
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        req.Method = "GET";
        req.AllowAutoRedirect = true;

        // allows for validation of SSL conversations
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };


        WebResponse respon = req.GetResponse();
        Stream res = respon.GetResponseStream();

        string ret = "";
        byte[] buffer = new byte[1048];
        int read = 0;
        while ((read = res.Read(buffer, 0, buffer.Length)) > 0)
        {
            //Console.Write(Encoding.ASCII.GetString(buffer, 0, read));
            ret += Encoding.ASCII.GetString(buffer, 0, read);
        }
        return ret;

采纳答案by Joseph Anderson

I enabled logging using this code:

我使用以下代码启用了日志记录:

http://blogs.msdn.com/b/dgorti/archive/2005/09/18/471003.aspx

http://blogs.msdn.com/b/dgorti/archive/2005/09/18/471003.aspx

The log was in the bin/debug folder (I was in Debug mode for my console app). You need to add the security protocol type as SSL 3

日志位于 bin/debug 文件夹中(我的控制台应用程序处于调试模式)。您需要将安全协议类型添加为 SSL 3

I received an algorithm mismatch in the log. Here is my new code:

我在日志中收到算法不匹配。这是我的新代码:

        // You must change the URL to point to your Web server.
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        req.Method = "GET";
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;


        // Skip validation of SSL/TLS certificate
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };


        WebResponse respon = req.GetResponse();
        Stream res = respon.GetResponseStream();

        string ret = "";
        byte[] buffer = new byte[1048];
        int read = 0;
        while ((read = res.Read(buffer, 0, buffer.Length)) > 0)
        {
            Console.Write(Encoding.ASCII.GetString(buffer, 0, read));
            ret += Encoding.ASCII.GetString(buffer, 0, read);
        }
        return ret;

回答by Jon Wagner

This could be caused by a few things (most likely to least likely):

这可能是由一些事情引起的(最有可能是最不可能的):

  1. The server's SSL certificate is untrusted by the client. Easiest check is to point a browser at the URL and see if you get an SSL lock icon. If you get a broken lock, icon, click on it to see what the issue is:

    1. Expired dates - get a new SSL certificate
    2. Name does not match - make sure that your URL uses the same server name as the certificate.
    3. Not signed by a trusted authority - buy a certificate from an authority such as Verisign, or add the certificate to the client's trusted certificate store.
    4. In test environments you could update your certificate validator to skip access checks. Don't do this in production.
  2. Server is requiring Client SSL certificate - in this case you would have to update your code to sign the request with a client certificate.

  1. 客户端不信任服务器的 SSL 证书。最简单的检查是将浏览器指向 URL 并查看是否有 SSL 锁定图标。如果您的锁坏了,图标,请单击它以查看问题所在:

    1. 过期日期 - 获取新的 SSL 证书
    2. 名称不匹配 - 确保您的 URL 使用与证书相同的服务器名称。
    3. 未由受信任的机构签名 - 从 Verisign 等机构购买证书,或将证书添加到客户端的受信任证书库。
    4. 在测试环境中,您可以更新证书验证器以跳过访问检查。不要在生产中这样做。
  2. 服务器需要客户端 SSL 证书 - 在这种情况下,您必须更新代码以使用客户端证书签署请求。

回答by glm

I had to enable other security protocol versions to resolve the issue:

我必须启用其他安全协议版本才能解决此问题:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
        | SecurityProtocolType.Tls11
        | SecurityProtocolType.Tls12
        | SecurityProtocolType.Ssl3;

回答by Rajesh Pathakoti

Please see below link once. SecurityProtocolType.SsL3 is now old.

请看下面的链接一次。SecurityProtocolType.SsL3 现在已经过时了。

http://codemust.com/poodle-vulnerability-fix-openssl/

http://codemust.com/poodle-vulnerability-fix-openssl/

回答by Craig - MSFT

Similar to an existing answerbut in PowerShell:

类似于现有答案,但在 PowerShell 中:

[System.Net.ServicePointManager]::SecurityProtocol = `
[System.Net.SecurityProtocolType]::Tls11 -bor 
[System.Net.SecurityProtocolType]::Tls12 -bor `   
[System.Net.SecurityProtocolType]::Tls -bor `
[System.Net.SecurityProtocolType]::Ssl3

Then calling Invoke-WebRequest should work.

然后调用 Invoke-WebRequest 应该可以工作。

Got this from anonymous feedback, good suggestion: Simpler way to write this would be:

从匿名反馈中得到这个,很好的建议:写这个的更简单的方法是:

[System.Net.ServicePointManager]::SecurityProtocol = @("Tls12","Tls11","Tls","Ssl3")

Found this fantastic and related post by Jaykul: Validating Self-Signed Certificates From .Net and PowerShell

找到了 Jaykul 的这篇精彩的相关文章:Validating Self-Signed Certificates From .Net and PowerShell

回答by granadaCoder

I found the type of certificate also comes into play.

我发现证书的类型也起作用。

I had a cert that was:

我有一个证书是:

(the below output was in mmc , certificate properties )

(以下输出在 mmc 中,证书属性)

Digital Signature, Key Encipherment (a0)

数字签名、密钥加密 (a0)

(the below output was from my C# code below)

(下面的输出来自我下面的 C# 代码)

X509Extension.X509KeyUsageExtension.KeyUsages='KeyEncipherment, DigitalSignature'X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature='True' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment='True' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='False'

X509Extension.X509KeyUsageExtension.KeyUsages = 'KeyEncipherment,的DigitalSignature'X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags。的DigitalSignature = ''X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly =' FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment =”' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='False'

the above did notwork.

以上做工作。

===============================

================================

Then another certificate with :

然后是另一个证书:

(the below output was in mmc , certificate properties )

(以下输出在 mmc 中,证书属性)

Certificate Signing, Off-line CRL Signing, CRL Signing (06)

证书签名、离线 CRL 签名、CRL 签名 (06)

(the below output was from my C# code below)

(下面的输出来自我下面的 C# 代码)

X509Extension.X509KeyUsageExtension.KeyUsages='CrlSign, KeyCertSign'X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign='True' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign='True' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='False'

X509Extension.X509KeyUsageExtension.KeyUsages = 'CrlSign,KeyCertSign'X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign = ''X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment =' FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags。的DigitalSignature = '假' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement = 'FALSE' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign = ''X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment =' FALSE' X509KeyUsageExtension .KeyUsages.X509KeyUsageFlags.None='False'X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='False'

and it did work

确实有效

The below code will allow you to inspect your client certificate

下面的代码将允许您检查您的客户端证书

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MyNamespace
{
    public static class SecurityShower
    {
        public static void ShowHttpWebRequest(System.Net.HttpWebRequest hwr)
        {
            StringBuilder sb = new StringBuilder();
            if (null != hwr)
            {
                sb.Append("-----------------------------------------------HttpWebRequest" + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address.AbsolutePath='{0}'", hwr.Address.AbsolutePath) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address.AbsoluteUri='{0}'", hwr.Address.AbsoluteUri) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.Address='{0}'", hwr.Address) + System.Environment.NewLine);

                sb.Append(string.Format("HttpWebRequest.RequestUri.AbsolutePath='{0}'", hwr.RequestUri.AbsolutePath) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.RequestUri.AbsoluteUri='{0}'", hwr.RequestUri.AbsoluteUri) + System.Environment.NewLine);
                sb.Append(string.Format("HttpWebRequest.RequestUri='{0}'", hwr.RequestUri) + System.Environment.NewLine);

                foreach (X509Certificate cert in hwr.ClientCertificates)
                {
                    sb.Append("START*************************************************");
                    ShowX509Certificate(sb, cert);
                    sb.Append("END*************************************************");
                }
            }

            string result = sb.ToString();
            Console.WriteLine(result);
        }

        public static void ShowCertAndChain(X509Certificate2 cert)
        {
            X509Chain chain = new X509Chain();
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;

            ////chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCtlSignerRevocationUnknown &&
            ////X509VerificationFlags.IgnoreRootRevocationUnknown &&
            ////X509VerificationFlags.IgnoreEndRevocationUnknown &&
            ////X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown &&
            ////X509VerificationFlags.IgnoreCtlNotTimeValid;

            chain.Build(cert);

            ShowCertAndChain(cert, chain);
        }

        public static void ShowCertAndChain(X509Certificate cert, X509Chain chain)
        {
            StringBuilder sb = new StringBuilder();
            if (null != cert)
            {
                ShowX509Certificate(sb, cert);
            }

            if (null != chain)
            {
                sb.Append("-X509Chain(Start)-" + System.Environment.NewLine);
                ////sb.Append(string.Format("Cert.ChainStatus='{0}'", string.Join(",", chain.ChainStatus.ToList())) + System.Environment.NewLine);

                foreach (X509ChainStatus cstat in chain.ChainStatus)
                {
                    sb.Append(string.Format("X509ChainStatus::'{0}'-'{1}'", cstat.Status.ToString(), cstat.StatusInformation) + System.Environment.NewLine);
                }

                X509ChainElementCollection ces = chain.ChainElements;
                ShowX509ChainElementCollection(sb, ces);
                sb.Append("-X509Chain(End)-" + System.Environment.NewLine);
            }

            string result = sb.ToString();
            Console.WriteLine(result);
        }

        private static void ShowX509Extension(StringBuilder sb, int x509ExtensionCount, X509Extension ext)
        {
            sb.Append(string.Empty + System.Environment.NewLine);
            sb.Append(string.Format("--------X509ExtensionNumber(Start):{0}", x509ExtensionCount) + System.Environment.NewLine);
            sb.Append(string.Format("X509Extension.Critical='{0}'", ext.Critical) + System.Environment.NewLine);

            AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData);
            sb.Append(string.Format("Extension type: {0}", ext.Oid.FriendlyName) + System.Environment.NewLine);
            sb.Append(string.Format("Oid value: {0}", asndata.Oid.Value) + System.Environment.NewLine);
            sb.Append(string.Format("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine) + System.Environment.NewLine);
            sb.Append(asndata.Format(true) + System.Environment.NewLine);

            X509BasicConstraintsExtension basicEx = ext as X509BasicConstraintsExtension;
            if (null != basicEx)
            {
                sb.Append("-X509BasicConstraintsExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509BasicConstraintsExtension.CertificateAuthority='{0}'", basicEx.CertificateAuthority) + System.Environment.NewLine);
            }

            X509EnhancedKeyUsageExtension keyEx = ext as X509EnhancedKeyUsageExtension;
            if (null != keyEx)
            {
                sb.Append("-X509EnhancedKeyUsageExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509EnhancedKeyUsageExtension.EnhancedKeyUsages='{0}'", keyEx.EnhancedKeyUsages) + System.Environment.NewLine);
                foreach (Oid oi in keyEx.EnhancedKeyUsages)
                {
                    sb.Append(string.Format("------------EnhancedKeyUsages.Oid.FriendlyName='{0}'", oi.FriendlyName) + System.Environment.NewLine);
                    sb.Append(string.Format("------------EnhancedKeyUsages.Oid.Value='{0}'", oi.Value) + System.Environment.NewLine);
                }
            }

            X509KeyUsageExtension usageEx = ext as X509KeyUsageExtension;
            if (null != usageEx)
            {
                sb.Append("-X509KeyUsageExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509KeyUsageExtension.KeyUsages='{0}'", usageEx.KeyUsages) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.CrlSign) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DataEncipherment) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DecipherOnly) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DigitalSignature) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.EncipherOnly) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyAgreement) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyCertSign) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyEncipherment) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.None) != 0) + System.Environment.NewLine);
                sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.NonRepudiation) != 0) + System.Environment.NewLine);
            }

            X509SubjectKeyIdentifierExtension skIdEx = ext as X509SubjectKeyIdentifierExtension;
            if (null != skIdEx)
            {
                sb.Append("-X509SubjectKeyIdentifierExtension-" + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.Oid='{0}'", skIdEx.Oid) + System.Environment.NewLine);
                sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.SubjectKeyIdentifier='{0}'", skIdEx.SubjectKeyIdentifier) + System.Environment.NewLine);
            }

            sb.Append(string.Format("--------X509ExtensionNumber(End):{0}", x509ExtensionCount) + System.Environment.NewLine);
        }

        private static void ShowX509Extensions(StringBuilder sb, string cert2SubjectName, X509ExtensionCollection extColl)
        {
            int x509ExtensionCount = 0;
            sb.Append(string.Format("--------ShowX509Extensions(Start):for:{0}", cert2SubjectName) + System.Environment.NewLine);
            foreach (X509Extension ext in extColl)
            {
                ShowX509Extension(sb, ++x509ExtensionCount, ext);
            }

            sb.Append(string.Format("--------ShowX509Extensions(End):for:{0}", cert2SubjectName) + System.Environment.NewLine);
        }

        private static void ShowX509Certificate2(StringBuilder sb, X509Certificate2 cert2)
        {
            if (null != cert2)
            {
                sb.Append(string.Format("X509Certificate2.SubjectName.Name='{0}'", cert2.SubjectName.Name) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Subject='{0}'", cert2.Subject) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Thumbprint='{0}'", cert2.Thumbprint) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.HasPrivateKey='{0}'", cert2.HasPrivateKey) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.Version='{0}'", cert2.Version) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.NotBefore='{0}'", cert2.NotBefore) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.NotAfter='{0}'", cert2.NotAfter) + System.Environment.NewLine);
                sb.Append(string.Format("X509Certificate2.PublicKey.Key.KeySize='{0}'", cert2.PublicKey.Key.KeySize) + System.Environment.NewLine);

                ////List<X509KeyUsageExtension> keyUsageExtensions = cert2.Extensions.OfType<X509KeyUsageExtension>().ToList();
                ////List<X509Extension> extensions = cert2.Extensions.OfType<X509Extension>().ToList();

                ShowX509Extensions(sb, cert2.Subject, cert2.Extensions);
            }
        }

        private static void ShowX509ChainElementCollection(StringBuilder sb, X509ChainElementCollection ces)
        {
            int x509ChainElementCount = 0;
            foreach (X509ChainElement ce in ces)
            {
                sb.Append(string.Empty + System.Environment.NewLine);
                sb.Append(string.Format("----X509ChainElementNumber:{0}", ++x509ChainElementCount) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.SubjectName.Name='{0}'", ce.Certificate.SubjectName.Name) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.Issuer='{0}'", ce.Certificate.Issuer) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.Thumbprint='{0}'", ce.Certificate.Thumbprint) + System.Environment.NewLine);
                sb.Append(string.Format("X509ChainElement.Cert.HasPrivateKey='{0}'", ce.Certificate.HasPrivateKey) + System.Environment.NewLine);

                X509Certificate2 cert2 = ce.Certificate as X509Certificate2;
                ShowX509Certificate2(sb, cert2);

                ShowX509Extensions(sb, cert2.Subject, ce.Certificate.Extensions);
            }
        }

        private static void ShowX509Certificate(StringBuilder sb, X509Certificate cert)
        {
            sb.Append("-----------------------------------------------" + System.Environment.NewLine);
            sb.Append(string.Format("Cert.Subject='{0}'", cert.Subject) + System.Environment.NewLine);
            sb.Append(string.Format("Cert.Issuer='{0}'", cert.Issuer) + System.Environment.NewLine);

            sb.Append(string.Format("Cert.GetPublicKey().Length='{0}'", cert.GetPublicKey().Length) + System.Environment.NewLine);

            X509Certificate2 cert2 = cert as X509Certificate2;
            ShowX509Certificate2(sb, cert2);
        }
    }
}