Search code examples
c#.netcomunmanagedmanaged

Proper way to set ServicePointManager.SecurityProcol when using an unmanaged executable


I have an unmanaged (C++) program that uses multiple managed (C#) DLLs via COM and I need those DLLs to use TLS1.2. All the DLLs target .NET 4.6 or higher, but that doesn't seem to matter.

When I run managed programs that target .NET 4.6 and 4.7 and call a managed DLL, the SecurityProtocol is set to Tls, Tls11, Tls12 andSystemDefault, respectively, and TLS1.2 is used. When I run my unmanaged program and call the same managed DLL, the SecurityProtocol is set to Ssl3, Tls and it does not use TLS1.2.

What doesn't work:

  • Setting the supportedRuntime in MyProgram.exe.config. Adding <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" /></startup> to the config file had no effect on the SecurityProtocol.

What works, but is not optimal:

  • Creating a new DLL that explicitly sets the SecurityProtocol and calling it in the unmanaged program before anything else; the SecurityProtocol will then be correctly set for calls to all other DLLs. This works well but I don't want to add another dependency to my project just for this.
  • Setting AppContextSwitchOverrides in the config file by adding the line <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> will cause the SecurityProtocol to be Tls, Tls11, Tls12. This works well, but seems like a hack that exploits undocumented (and possibly unintended) behavior.

Is there any better way to get the managed DLLs' SecurityProtocol to use either Tls12 or SystemDefault when running my unmanaged program? Thanks.


Solution

  • Simon Mourier was correct, setting <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> in the config file is the official way to add Tls12 as a default protocol.