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

本文关键字:SSL TLS 安全 通道 创建 请求 | 更新日期: 2023-09-27 18:35:52

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

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

我可以更改 HttpWebRequest 来解决此问题吗?

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

    // 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;

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

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

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

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

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

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

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

        // 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;

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

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

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

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

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

Jaykul发现了这篇精彩且相关的文章:验证来自.Net和PowerShell的自签名证书

这可能是由以下几件事引起的(最有可能到最不可能):

  1. 客户端不信任服务器的 SSL 证书。最简单的检查是将浏览器指向 URL,看看您是否获得 SSL 锁定图标。如果你得到一个坏锁,图标,点击它看看问题是什么:

    1. 过期日期 - 获取新的 SSL 证书
    2. 名称不匹配 - 确保您的 URL 使用与证书相同的服务器名称。
    3. 未由受信任的颁发机构签名 - 从威瑞信等颁发机构购买证书,或将证书添加到客户端的受信任证书存储中。
    4. 在测试环境中,您可以更新证书验证程序以跳过访问检查。不要在生产中执行此操作。
  2. 服务器需要客户端 SSL 证书 - 在这种情况下,您必须更新代码才能使用客户端证书对请求进行签名。

对于.Net v4.0,我注意到,在创建HttpWebRequest对象之前,将ServicePointManager.SecurityProtocol的值设置为(SecurityProtocolType)3072有所帮助。

还收到"无法创建 SSL/TLS 安全通道"错误。 这就是对我有用的东西。System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;

不幸的是,上面提到的答案都不适合我。下面列出的代码为我创造了一个奇迹。万一它帮助了某人。

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

这必须在创建 HttpWebRequest 之前设置。

请参阅下面的链接一次。SecurityProtocolType.SsL3 现在已经很旧了。

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

按如下方式定义安全协议。这解决了我的问题

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

我发现证书的类型也开始发挥作用。

我有一个证书是:

(以下输出为MMC,证书属性)

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

(下面的输出来自下面的 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.Nondediation='false'

以上不起作用。

====

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

然后是另一个证书:

(以下输出为MMC,证书属性)

证书签名, 脱机 CRL 签名

, CRL 签名 (06)

(下面的输出来自下面的 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.Nondediation='false'

确实有效

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

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);
        }
    }
}

来自@sameerfair评论

"对于.Net v4.0,我注意到,将ServicePointManager.SecurityProtocol的值设置为(SecurityProtocolType)3072,但在创建HttpWebRequest对象之前有所帮助。

上述建议对我有用。以下是对我有用的代码行

var securedwebserviceurl="https://somedomain.com/service";
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11;
// Skip validation of SSL/TLS certificate
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
var httpWebRequest = (HttpWebRequest)WebRequest.Create(securedwebserviceurl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.ProtocolVersion= HttpVersion.Version10;
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
string responseFromServer = streamReader.ReadToEnd();
}

这对我有用:

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

这对我有用:

ServicePointManager.ServerCertificateValidationCallback = (snder, cert, chain, error) => true;

如果它不起作用,它可能适用于其他解决方案,如下所示:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = (snder, cert, chain, error) => true;

当托管应用程序的服务器仅支持 TLS 1.2 时,它可能很有用。在这种情况下,您需要删除旧的不安全协议,并仅保留TLS 1.2:

// Remove insecure protocols (SSL3, TLS 1.0, TLS 1.1)
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11;
// Add TLS 1.2
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
<</div> div class="answers">

此错误是 AppLocker 阻止 PowerShell 脚本的症状。一旦我从白名单位置运行它,就没有更多的问题了。