未处于管理模式时,在 TLS 1.2 连接期间无法创建 SSL/TLS 安全通道错误
Could not create SSL/TLS secure channel error during TLS 1.2 connection when not in admin mode
过去两天我一直在寻找答案,但仍然不知道从哪里开始调查。
我有一个 C# .net 标准库和一个允许我从 REST api 获取数据的 powershell 脚本。 powershell 脚本如下所示。
$cert = Get-ChildItem -Path Cert:\LocalMachine\My\<Thumbprint>
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri “https://some.url.to.get.my.data” -Method Get -Certificate $cert
直到最近,这里提到的这个脚本和 C# 代码都对我有用(不是 运行 作为管理员)。现在给我带来麻烦并返回错误消息:
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At line:3 char:1
+ Invoke-WebRequest -Uri “https://some.url.to.get.my.data ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
我的 C# 应用程序中存在同样的问题。我设置了
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
我设置了 X509 证书(此处未显示)并使用
进行调用
HttpClient.GetStringAsync(string requestUri).Result;
通话挂起,永远不会 returns。
有趣的是,如果我是 运行 Powershell 或 Visual Studio 管理员模式,Powershell 和 C# 代码都可以正常工作。
在我的沮丧中,我尝试通过 wireshark 查看我的客户端和服务器之间的调用。通过比较工作呼叫和非工作呼叫之间的呼叫模式,我可以看出握手似乎工作正常。至少在最初直到服务器应该发送数据之前。客户端出于某种原因向服务器发送 [FIN, ACK] 调用,连接终止。
我欢迎您提出任何建议。
谢谢。
我在另一个 .NET 应用程序中遇到了类似的问题,请验证是否已设置以下注册表项,另请注意,根据您的 .NET 和/或操作系统版本,可能需要特定的补丁以获取更多信息,请参阅:https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
$RegistryKeys = @(
@{
Path = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319"
Name = "SystemDefaultTlsVersions"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319"
Name = "SchUseStrongCrypto"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"
Name = "SystemDefaultTlsVersions"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"
Name = "SchUseStrongCrypto"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
Name = "Enabled"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
Name = "DisabledByDefault"
Value = "0"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"
Name = "Enabled"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"
Name = "DisabledByDefault"
Value = "0"
PropertyType = "DWord"
}
)
一些用于测试的代码:
$ErrorActionPreference = 'Stop'
$VerbosePreference = 'Continue'
Foreach ($RegistryKey in $RegistryKeys) {
# * Validate Path
# This code will check if the Path exists.
Write-Verbose "Processing '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
Write-Verbose "Validating if path '$($RegistryKey.Path)' exists"
If (-Not (Test-Path -Path $RegistryKey.Path)) {
Write-Warning "Path '$($RegistryKey.Path)' doest not exist"
Continue
}
Write-Verbose "Path '$($RegistryKey.Path)' exists"
# * Validate Property
# This code will check if the property exists.
Write-Verbose "Reading properties for'$($RegistryKey.Path)'"
$Properties = Get-ItemProperty -Path $RegistryKey.Path
Write-Verbose "Validating if property '$($RegistryKey.Name)' exists"
If (-Not ($RegistryKey.Name -in ($Properties | Get-Member).Name)) {
Write-Warning "Property '$($RegistryKey.Name)' doest not exist"
Continue
}
Write-Verbose "Property '$($RegistryKey.Name)' exists"
# * Validate Property value
# This code will check if the configured value is correct.
Write-Verbose "Validating if property value is set to '$($RegistryKey.Value)'"
If (-Not ((Get-ItemProperty -Path $RegistryKey.Path -Name $RegistryKey.Name)."$($RegistryKey.Name)" -eq $RegistryKey.Value)) {
Write-Warning "Property value is incorrect for '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
Continue
}
Write-Verbose "Property value is correct for '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
}
就我而言,事实证明问题确实出在获取证书上。我最初在开发过程中在当前用户帐户中拥有该证书,该证书可以正常工作。将证书移动到本地计算机帐户后,我开始遇到这个问题。
解决方案是通过证书管理器授予我的用户帐户访问特定证书的权限 > 右键单击证书 > 所有任务 > 管理私钥。然后将我的用户帐户添加到列表中。
过去两天我一直在寻找答案,但仍然不知道从哪里开始调查。
我有一个 C# .net 标准库和一个允许我从 REST api 获取数据的 powershell 脚本。 powershell 脚本如下所示。
$cert = Get-ChildItem -Path Cert:\LocalMachine\My\<Thumbprint>
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri “https://some.url.to.get.my.data” -Method Get -Certificate $cert
直到最近,这里提到的这个脚本和 C# 代码都对我有用(不是 运行 作为管理员)。现在给我带来麻烦并返回错误消息:
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At line:3 char:1
+ Invoke-WebRequest -Uri “https://some.url.to.get.my.data ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
我的 C# 应用程序中存在同样的问题。我设置了
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
我设置了 X509 证书(此处未显示)并使用
进行调用HttpClient.GetStringAsync(string requestUri).Result;
通话挂起,永远不会 returns。
有趣的是,如果我是 运行 Powershell 或 Visual Studio 管理员模式,Powershell 和 C# 代码都可以正常工作。
在我的沮丧中,我尝试通过 wireshark 查看我的客户端和服务器之间的调用。通过比较工作呼叫和非工作呼叫之间的呼叫模式,我可以看出握手似乎工作正常。至少在最初直到服务器应该发送数据之前。客户端出于某种原因向服务器发送 [FIN, ACK] 调用,连接终止。
我欢迎您提出任何建议。
谢谢。
我在另一个 .NET 应用程序中遇到了类似的问题,请验证是否已设置以下注册表项,另请注意,根据您的 .NET 和/或操作系统版本,可能需要特定的补丁以获取更多信息,请参阅:https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
$RegistryKeys = @(
@{
Path = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319"
Name = "SystemDefaultTlsVersions"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319"
Name = "SchUseStrongCrypto"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"
Name = "SystemDefaultTlsVersions"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"
Name = "SchUseStrongCrypto"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
Name = "Enabled"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
Name = "DisabledByDefault"
Value = "0"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"
Name = "Enabled"
Value = "1"
PropertyType = "DWord"
}
@{
Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"
Name = "DisabledByDefault"
Value = "0"
PropertyType = "DWord"
}
)
一些用于测试的代码:
$ErrorActionPreference = 'Stop'
$VerbosePreference = 'Continue'
Foreach ($RegistryKey in $RegistryKeys) {
# * Validate Path
# This code will check if the Path exists.
Write-Verbose "Processing '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
Write-Verbose "Validating if path '$($RegistryKey.Path)' exists"
If (-Not (Test-Path -Path $RegistryKey.Path)) {
Write-Warning "Path '$($RegistryKey.Path)' doest not exist"
Continue
}
Write-Verbose "Path '$($RegistryKey.Path)' exists"
# * Validate Property
# This code will check if the property exists.
Write-Verbose "Reading properties for'$($RegistryKey.Path)'"
$Properties = Get-ItemProperty -Path $RegistryKey.Path
Write-Verbose "Validating if property '$($RegistryKey.Name)' exists"
If (-Not ($RegistryKey.Name -in ($Properties | Get-Member).Name)) {
Write-Warning "Property '$($RegistryKey.Name)' doest not exist"
Continue
}
Write-Verbose "Property '$($RegistryKey.Name)' exists"
# * Validate Property value
# This code will check if the configured value is correct.
Write-Verbose "Validating if property value is set to '$($RegistryKey.Value)'"
If (-Not ((Get-ItemProperty -Path $RegistryKey.Path -Name $RegistryKey.Name)."$($RegistryKey.Name)" -eq $RegistryKey.Value)) {
Write-Warning "Property value is incorrect for '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
Continue
}
Write-Verbose "Property value is correct for '$($RegistryKey.Path)' '$($RegistryKey.Name)'"
}
就我而言,事实证明问题确实出在获取证书上。我最初在开发过程中在当前用户帐户中拥有该证书,该证书可以正常工作。将证书移动到本地计算机帐户后,我开始遇到这个问题。
解决方案是通过证书管理器授予我的用户帐户访问特定证书的权限 > 右键单击证书 > 所有任务 > 管理私钥。然后将我的用户帐户添加到列表中。