无法从 .NET C# 创建 SSL/TLS 安全通道
Could not create SSL/TLS secure channel from .NET C#
我试图在我的服务器 windows 2008 R2 上调用 API,但我不断收到此错误:
无法创建 SSL/TLS 安全通道
我正在使用 LocalSystem 帐户将应用程序作为 Windows 服务启动。
我从 Stack Overflow 的一些问题中尝试了很多东西来开始它,但是 none 这些作品:
使用 AppContext 开关
没有 AppContext 开关
在安全协议上仅使用 SSL 协议 1.2
未更改 SecurityProcotol
ExpectContinue = 100
//Config
const string DontEnableSystemDefaultTlsVersions = @"Switch.System.Net.DontEnableSystemDefaultTlsVersions";
const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto";
const string DisableUsingServicePointManagerSecurityProtocols = @"Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols";
const string DontEnableSystemDefaultTlsVersionsServiceModel = @"Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions";
AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, false);
AppContext.SetSwitch(DontEnableSystemDefaultTlsVersions, true);
AppContext.SetSwitch(DisableUsingServicePointManagerSecurityProtocols, false);
AppContext.SetSwitch(DontEnableSystemDefaultTlsVersionsServiceModel, true);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
//API config and Call
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(message.Url);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = message.Method;
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(message.Content);
request.ContentLength = byteArray.Length;
request.ContentType = message.ContentType;
request.UserAgent = message.UserAgent;
request.Accept = message.Accept;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
API 需要 TLS 1.2+ 才能被调用。
我测试了 Internet Explorer 看是否可以调用 TLS 1.2,好像可以调用,我用的是这个 https://browserleaks.com/ssl :
BrowserLeak
我尝试通过 Postman 在线调用 API(使用 Chrome)和服务器上的 Postman 应用程序,两者都可以毫无问题地调用 API。
与 SoapUI 相同,它有效。
它在我的电脑上工作 (Windows 10),在服务器上不工作,相同 C# 代码。
我试过改框架,4.0、4.5、4.6、4.8,好像没什么变化。
我有 SSL 握手,但没有太大帮助,它说发生了握手失败 (02 28):
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Send() -> Int32#174
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] 00000000 : 15 03 03 00 02 : .....
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Receive() -> Int32#5
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] 00000005 : 02 28 : .(
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
Cipher suite 好像不错,我在套件开头有 API 要求的前 3 个 Cipher suite。
API 需要 ISRG 根 X1 证书,该证书位于受信任的根证书颁发机构存储中。
我使用了windows中的工具来修改注册表
https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392
它启用了 TLS 1.2,在我启动该工具之前它没有在 browserleaks 中激活。
还禁用了 SSL 2.0 和 SSL3.0,并激活了 TLS1.0、TLS1.1 和 TLS1.2:
Secure channel registry
我似乎找不到解决方案来让它工作。
我怎样才能找到问题的线索?
我们发现了问题,API 所需的密码套件与 windows 服务器 2008 R2 不兼容,我们通过
验证了密码套件
https://www.ssllabs.com/ssltest/ 与 url 的 api
然后将其与位于此处的服务器上的密码套件进行比较:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
和 none 匹配。
我试图在我的服务器 windows 2008 R2 上调用 API,但我不断收到此错误: 无法创建 SSL/TLS 安全通道
我正在使用 LocalSystem 帐户将应用程序作为 Windows 服务启动。
我从 Stack Overflow 的一些问题中尝试了很多东西来开始它,但是 none 这些作品:
使用 AppContext 开关
没有 AppContext 开关
在安全协议上仅使用 SSL 协议 1.2
未更改 SecurityProcotol
ExpectContinue = 100
//Config const string DontEnableSystemDefaultTlsVersions = @"Switch.System.Net.DontEnableSystemDefaultTlsVersions"; const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto"; const string DisableUsingServicePointManagerSecurityProtocols = @"Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols"; const string DontEnableSystemDefaultTlsVersionsServiceModel = @"Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions"; AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, false); AppContext.SetSwitch(DontEnableSystemDefaultTlsVersions, true); AppContext.SetSwitch(DisableUsingServicePointManagerSecurityProtocols, false); AppContext.SetSwitch(DontEnableSystemDefaultTlsVersionsServiceModel, true); ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; //API config and Call HttpWebRequest request = (HttpWebRequest)WebRequest.Create(message.Url); request.Credentials = CredentialCache.DefaultCredentials; request.Method = message.Method; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); Byte[] byteArray = encoding.GetBytes(message.Content); request.ContentLength = byteArray.Length; request.ContentType = message.ContentType; request.UserAgent = message.UserAgent; request.Accept = message.Accept; using (Stream dataStream = request.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); }
API 需要 TLS 1.2+ 才能被调用。
我测试了 Internet Explorer 看是否可以调用 TLS 1.2,好像可以调用,我用的是这个 https://browserleaks.com/ssl : BrowserLeak
我尝试通过 Postman 在线调用 API(使用 Chrome)和服务器上的 Postman 应用程序,两者都可以毫无问题地调用 API。 与 SoapUI 相同,它有效。
它在我的电脑上工作 (Windows 10),在服务器上不工作,相同 C# 代码。
我试过改框架,4.0、4.5、4.6、4.8,好像没什么变化。
我有 SSL 握手,但没有太大帮助,它说发生了握手失败 (02 28):
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Send() -> Int32#174
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] 00000000 : 15 03 03 00 02 : .....
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Receive() -> Int32#5
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] 00000005 : 02 28 : .(
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
Cipher suite 好像不错,我在套件开头有 API 要求的前 3 个 Cipher suite。
API 需要 ISRG 根 X1 证书,该证书位于受信任的根证书颁发机构存储中。
我使用了windows中的工具来修改注册表 https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392 它启用了 TLS 1.2,在我启动该工具之前它没有在 browserleaks 中激活。
还禁用了 SSL 2.0 和 SSL3.0,并激活了 TLS1.0、TLS1.1 和 TLS1.2: Secure channel registry
我似乎找不到解决方案来让它工作。 我怎样才能找到问题的线索?
我们发现了问题,API 所需的密码套件与 windows 服务器 2008 R2 不兼容,我们通过
验证了密码套件https://www.ssllabs.com/ssltest/ 与 url 的 api
然后将其与位于此处的服务器上的密码套件进行比较:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
和 none 匹配。