![](/img/trans.png)
[英]The request was aborted: Could not create SSL/TLS secure channel - SecurityProtocol behavior
[英]The request was aborted: Could not create SSL/TLS secure channel
我的客戶已告知我有關他們的 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;
我必須啟用其他安全協議版本才能解決此問題:
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 的這篇精彩的相關文章: Validating Self-Signed Certificates From .Net and PowerShell
這可能是由一些事情引起的(最有可能是最不可能的):
客戶端不信任服務器的 SSL 證書。 最簡單的檢查是將瀏覽器指向 URL 並查看是否有 SSL 鎖定圖標。 如果您的鎖壞了,圖標,請單擊它以查看問題所在:
服務器需要客戶端 SSL 證書 - 在這種情況下,您必須更新代碼以使用客戶端證書簽署請求。
對於 .Net v4.0 我注意到,在創建 HttpWebRequest 對象之前將 ServicePointManager.SecurityProtocol 的值設置為 (SecurityProtocolType)3072 有幫助。
還收到“無法創建 SSL/TLS 安全通道”錯誤。 這對我有用。 System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
請看下面的鏈接一次。 SecurityProtocolType.SsL3 現在已經過時了。
如下定義 SecurityProtocol。這對我的問題進行了排序
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
不幸的是,上面提到的答案都不適合我。 下面列出的代碼對我來說是一個奇跡。 如果它幫助某人。
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
這必須在創建 HttpWebRequest 之前設置。
我發現證書的類型也起作用。
我有一個證書是:
(以下輸出在 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 = '真'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'
以上沒有工作。
================================
然后是另一個證書:
(以下輸出在 mmc 中,證書屬性)
證書簽名、離線 CRL 簽名、CRL 簽名 (06)
(下面的輸出來自我下面的 C# 代碼)
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'
它確實有效
下面的代碼將允許您檢查您的客戶端證書
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.