Reputation: 41
I'm upgrading a Visual C++/CLI MFC DLL so that TLS 1.2 is used by default in order to comply with the requirement soon to be enforced Authorize.Net.
The DLL is now set to target .NET 4.7 and .NET 4.7 is installed on the Windows 10 machine it runs on, but TLS 1.2 is not enabled by default, as it should be with .NET 4.6 and above.
I'd like to avoid having to modify the DLL with the code:
ServicePointManager::SecurityProtocol = SecurityProtocolType::Tls12;
I tested compatibility with TLS 1.2 by using the following code, which always throws an exception:
HttpWebRequest ^httpReq = (HttpWebRequest ^)(WebRequest::Create("https://www.ssllabs.com:10303"));
HttpWebResponse ^ httpResp = (HttpWebResponse ^)httpReq->GetResponse();
if (((int)httpResp->StatusCode >= 200) &&
((int)httpResp->StatusCode <= 299))
{
// Log message indicating success
}
I found the default security protocol by using:
int protocolType = (int)ServicePointManager::SecurityProtocol;
which returned a value of 240, indicating:
SecurityProtocolType.Tls | SecurityProtocolType.Ssl3
A different version of the DLL, written in C# & targeted to .NET 4.6, targets TLS 1.2 by default on Windows Server 2012 R2 with .NET 4.6 installed, without having to explicitly set the SecurityProtocol via the ServicePointManager.
Why wouldn't TLS 1.2 be enabled by default for the DLL on the Windows 10 system if everything targets & runs .NET 4.7? Could it have something to do with the fact the DLL is C++/CLI and being called by an older VB6 application? I'm simply perplexed.
Upvotes: 4
Views: 4386
Reputation: 111
Did you try to specify the run time target framework in config?
<system.web>
<httpRuntime targetFramework="4.7.2"/>
</system.web>
This setting makes application to redirect security protocol selection to OS without hard coding certain values to ServicePointManager.SecurityProtocol
In this case
System.Net.ServicePointManager.SecurityProtocol == SystemDefault
Upvotes: 1
Reputation: 8308
I don’t understand the mechanism myself. I want to and will update this if I find more information. However, from the docs on ServicePointManager.SecurityProtocol
:
The .NET Framework 4.6 includes a new security feature that blocks insecure cipher and hashing algorithms for connections. Applications using TLS/SSL through APIs such as HttpClient, HttpWebRequest, FTPClient, SmtpClient, SslStream, etc. and targeting .NET Framework 4.6 get the more-secure behavior by default.
This states that the default depends on the target framework of your compiled code. To update your application’s targeting to get the new behavior, change the target in VS in the project’s Properties to at least 4.6 and recompile. Depending on how .net detects which framework your application targets, you may be able to avoid recompiling and edit the assembly’s metadata directly to change its targeting and get .net to return the newer values.
The reason .net-4.5+ changes behavior depending on what framework you’re targeting is to try to avoid breaking compatibility when releasing a new version. Even though your app which targets .net-4.5 uses the .net-4.7.1 or newer runtime, that .net-4.7.1 will, for certain APIs and operations, pretend to behave like .net-4.5. The idea is that the developer may need to make code changes after retargeting to .net-4.7 before the application will run correctly.
Upvotes: 1