I'm trying to create a CngKey
in .NET 4.7.2 from a PEM file so I can sign an Apple auth JWT token.
It all worked fine in dev, but when I deployed to staging I was met with a "file not found error" from calling CngKey.Import()
. Of course. The app is running under some IIS app pool user with no user directory structure for the OS to store keys in.
Since then I've been trying to use CngKey.Create()
to import a machine-wide key, but I keep getting the following unhelpful error:
System.Security.Cryptography.CryptographicException: 'The requested operation is not supported.'
This exception was originally thrown at this call stack:
System.Security.Cryptography.NCryptNative.SetProperty(Microsoft.Win32.SafeHandles.SafeNCryptHandle, string, byte[], System.Security.Cryptography.CngPropertyOptions)
System.Security.Cryptography.CngKey.SetKeyProperties(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle, System.Security.Cryptography.CngKeyCreationParameters)
System.Security.Cryptography.CngKey.Create(System.Security.Cryptography.CngAlgorithm, string, System.Security.Cryptography.CngKeyCreationParameters)
SigningTest.Program.MachineKey() in Program.cs
SigningTest.Program.Main() in Program.cs
Here is my current code:
var keyParameters = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
KeyUsage = CngKeyUsages.AllUsages,
Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
UIPolicy = new CngUIPolicy(CngUIProtectionLevels.None)
};
// KeyMeat is the part of the PEM file between "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----"
var keyBytes = Convert.FromBase64String(KeyMeat);
keyParameters.Parameters.Add(new CngProperty(
CngKeyBlobFormat.GenericPrivateBlob.Format,
keyBytes,
CngPropertyOptions.None)
);
var privateKey = CngKey.Create(CngAlgorithm.ECDsaP256, "someName", keyParameters);
Note that the error occurs at CngKey.Create()
, but only when keyParameters.Parameters.Add()
is not commented out.