Amusing Cryptography on Windows

Amusing fact #1: .NET framework does not have built-in class to load RSA private key from PKCS#1 (PEM) representation.
I borrowed this:

Amusing fact #2: creating an RSA key requires file system access. To the user profile. If you are running under an ASP.NET app pool user that has no profile, you get this:

System.Security.Cryptography.CryptographicException: The system cannot find the file specified.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils._CreateCSP(CspParameters param, Boolean randomKeyContainer, SafeProvHandle& hProv)
   at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
   at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
   at {my method}

To fix, one must either create the user profile, or use CspProviderFlags.UseMachineKeyStore when creating RSACryptoServiceProvider. If you choose the latter, make sure the user has write access to C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. I believe %AllUsersProfile%\Microsoft\Crypto\RSA\MachineKeys should be used to accommodate customized or non-English systems.

If you use machine storage, but the user does not have write access to the above folder, you’ll get
System.Security.Cryptography.CryptographicException: Access denied.

I am not certain which exact calls raises the exception: first Microsoft function on the call stack is GetKeyPair(), but I am not calling it: the actual culprit must be inlined. I suspect it is either new RSACryptoServiceProvider(CspParameters) or RSACryptoServiceProvider.ImportParameters(RsaParameterTraits), I did not have time to investigate which one.

Leave a Reply

Your email address will not be published. Required fields are marked *