This article addresses a common scenario Okta Admins may encounter when attempting to test a newly installed Okta MFA Credential Provider for Windows installation or after a system restore or .NET update. This error initially presents as a generic message when attempting to log in:
Multi Factor Authentication Failed
However, from referencing the OktaWidget.log file, there are System.Net.WebException errors similar to:
- exception thrown is = System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
- System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
- System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
- System.Net.WebException: The client and server cannot communicate because they do not possess a common algorithm
- System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host.
If unaware of how to access the OktaWidget.log file to troubleshoot errors, please see the parent article for Troubleshooting Okta MFA Credential Provider RDP Errors.
These errors tend to indicate issues with a "secure channel connection" or will outright report issues with SSL/TLS negotiation.
- Okta MFA Credential Provider for Windows
- Remote Desktop Protocol (RDP)
- Multi-Factor Authentication (MFA)
These errors occur as the server's .Net implementation is attempting to connect back with the Okta tenant and offers unsupported cipher suites in its CLIENT HELLO TLS Negotiation. These usually include ciphers from the SSLv3, TLSv1, and TLSv1.1 implementations, and Okta no longer supports anything less than TLS1.2. As Okta does not support older ciphers, instead of sending back a SERVER HELLO and continuing the negotiation to encrypt the HTTP communication, an Alert message is sent back, and the connection is reset.
This behavior can be further confirmed with a packet capture, which in our example clearly shows the server sending out unsupported TLSv1 ciphers:
To resolve these issues, the server will need to be modified so that it will only use strong encryption, meaning TLSv1.2+. From our manual chapter on Troubleshooting the MFA for Windows Credential Provider. The following PowerShell script provides an example of how to perform the necessary modification.
Open a PowerShell terminal as administrator and execute the following script:
$is64bit = [IntPtr]::Size * 8 -eq 64
Write-Host "Is 64-bit script: $is64bit"
#helper function to check for if 0x800 bit is set
function checkTls12Bit([Int] $regValue) {
return ($regValue -band 0x800) -ne 0x800
}
function setRegKeyToBitValue([string] $regBranch, [string] $regKey) {
$current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue
if ($current -eq $null) {
Write-Host "$regBranch\$regKey does not exist. No change."
return $false
}
$regValue = $current.$regKey
if ($regValue -eq $null -or (checkTls12Bit $regValue) ) {
if ($regValue -eq $null) {
$regValue = 0x800
} else {
$regValue = $regValue -bor 0x800
}
$p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value $regValue -ErrorAction Stop -Force
Write-Host "Updated $regBranch\$regKey value to $regValue"
return $true
}
Write-Host "$regBranch\$regKey value is $regValue. No change."
return $false
}
function setRegKeyToValueOfOne([string] $regBranch, [string] $regKey) {
$current = Get-ItemProperty -Path $regBranch -ErrorAction SilentlyContinue
if ($current -eq $null) {
Write-Host "$regBranch\$regKey does not exist. No change."
return $false
}
if ($current.$regKey -ne 1) {
$p = New-ItemProperty $regBranch -Name $regKey -PropertyType DWord -Value 1 -ErrorAction Stop -Force
Write-Host "Updated $regBranch\$regKey value to 1"
return $true
}
Write-Host "$regBranch\$regKey value is 1. No change."
return $false
}
#setup .net tls settings
function setupTls4NET([boolean]$is64bit, [string]$regBranch, [string]$reg32bitBranch) {
# https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
$updated = setRegKeyToValueOfOne $regBranch "SchUseStrongCrypto"
$updated = (setRegKeyToValueOfOne $regBranch "SystemDefaultTlsVersions") -or $updated
if ($is64bit) {
$updated = (setRegKeyToValueOfOne $reg32bitBranch "SchUseStrongCrypto") -or $updated
$updated = (setRegKeyToValueOfOne $reg32bitBranch "SystemDefaultTlsVersions") -or $updated
}
return $updated
}
# https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
$version = Get-ItemProperty -Path "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release
# 394254 - .NET Framework 4.6.1, which is the current target of the installer
if ($version.Release -ge 394254) {
$ev = [environment]::Version
$v = "v" + $ev.Major + "." + $ev.Minor + "." + $ev.Build
$updated = setupTls4NET $is64bit "HKLM:\SOFTWARE\Microsoft\.NETFramework\$v" "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\$v"
# https://support.microsoft.com/en-ca/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
# updated the 32-bit branches if we are on 64-bit machine
if ($is64bit) {
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" "DefaultSecureProtocols") -or $updated
$updated = (setRegKeyToBitValue "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
}
# current user settings
$updated = (setRegKeyToBitValue "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
# local system account
$userSid = ".DEFAULT"
$updated = (setRegKeyToBitValue "Registry::HKEY_USERS\$userSid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" "SecureProtocols") -or $updated
if ($updated) {
Write-Host "Done. Updated required settings."
}
else
{
Write-Host "Done. No updates are required."
}
}
else
{
Write-Host "No changes were made. Your version of .NET Framework is earlier version than 4.6.1, please upgrade."
}
