I have a C# program (running on .NET 8) that signs data using an RSA key that is stored in Windows cert-/keystore. The key had been imported using Windows certmgr.msc into the "Personal" store. The import option "High security" (password required) + virtualization based security (makes the key non-exportable) were activated in the import dialog.
static void Main()
{
string subjectName = "selfsigned";
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName,
subjectName,validOnly: false);
if (certs.Count == 0)
{
Console.WriteLine($"Certificate containing subject '{subjectName}' not found.");
return;
}
X509Certificate2 cert = certs[0];
using (RSA rsa = cert.GetRSAPrivateKey()) // fails here
{
if (rsa == null)
{
Console.WriteLine("Certificate does not have an RSA private key.");
return;
}
// ... do something with the key
}
}
}
The code works on a Windows 10 system (22H2, latest updates), when executed Windows will show the password entry dialog, and if the password has been correctly entered, I can use the private key e.g. for signing data.
On a Windows 11 Enterprise system (24H2, latest updates) however, it fails with the error "invalid handle". The password entry dialog is never shown. The same on a second Win 11 Home system.
Error:
Unhandled exception.
System.Security.Cryptography.CryptographicException: Das angegebene Handle ist ungültig.at System.Security.Cryptography.CngHelpers.GetProperty(SafeNCryptHandle ncryptHandle, String propertyName, CngPropertyOptions options)
at System.Security.Cryptography.CngKey.get_AlgorithmGroup()
at System.Security.Cryptography.RSACng.set_Key(CngKey value)
at System.Security.Cryptography.RSACng..ctor(CngKey key, Boolean transferOwnership)
at System.Security.Cryptography.X509Certificates.CertificatePal.<>c.b__68_1(CngKey cngKey)
at System.Security.Cryptography.X509Certificates.CertificatePal.GetPrivateKey[T](Func2 createCsp, Func2 createCng)
at System.Security.Cryptography.X509Certificates.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at Program.Main()
Is this a bug of Windows 11 or is the Windows 11 system configured in a way that prevents usage of such keys?
Note: The strange part is that if you activate VBS + High security but don't set an additional password so that the user only gets a confirmation dialog without password prompt, it works on both Windows versions without problems. Only if you set an additional password it will always fail on Windows 11.