I've spent last two days searching for answers and still have no idea as to where to begin my investigation.
I've got both a C# .net standard library as well as a powershell script that allows me to fetch data from a REST api. The powershell script looks like this.
$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
Both, this script and C# code mentioned here was working for me until recently (not running as administrator). Now it is giving me trouble and returning an error message:
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
Same problem exist in my C# application. I've set
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
I set the X509 Certificate (not shown here) and make a call using
HttpClient.GetStringAsync(string requestUri).Result;
The call hangs and never returns.
The interesting thing here is that both the Powershell and C# code works fine if I'm running the Powershell or Visual Studio in Administrator mode.
In my frustration, I tried looking at the calls between my client and the server via wireshark. By comparing the call pattern between working and non working call, I can tell that the handshaking appears to be working correctly. At least initially until just before the server is suppose to send the data. The client for some reason sends a [FIN, ACK] call to the server and the connection terminates.
I welcome any suggestion you might have.
Thanks.
I had a similair issue with another .NET Application, please verify if below registry keys have been set, also note that a specific patch may be reqruired based on your .NET and or OperatingSystem version for more information see: 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"
}
)
Some code to test this with:
$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)'"
}
In my case, it turns out that the problem indeed was fetching the certificate. I initially had the certificate in the Current User account during development which worked without any issue. Once I had moved the certificate under the Local Machine account, I started having this issue.
The solution was to give my user account permission to access the specific certificate via Certificate Manager > Right click on the Certificate > All Tasks > Manage Private Keys. Then add my user account to the list.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.