I have the following code which is used for (en/de)crypting a key which in turn is used for encrypting strings that are placed in clients headers some of which the application may cache. (they contain senstive information). The application in this case is ASP .Net core 2.0 running on IIS.
The encryption using the public key works just fine but the exception is thrown when i try to decrypt.
private string DecryptKey(string key)
{
if (this.Certificate == null || string.IsNullOrEmpty(key))
throw new Exception("A x509 certificate and string for decryption must be provided");
// Get the string as bytes
var encryptedBytes = Convert.FromBase64String(key);
if (!Certificate.HasPrivateKey)
throw new Exception("x509 certificate does not contain a private key for decryption");
using (var rsa = Certificate.GetRSAPrivateKey())
{
var result = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA512); // **Exception is thrown here**
return ASCIIEncoding.ASCII.GetString(result);
}
}
private string EncryptKey(string key)
{
if (this.Certificate == null || string.IsNullOrEmpty(key))
throw new Exception("A x509 certificate and string for decryption must be provided");
// Get the string as bytes
var bytes = ASCIIEncoding.ASCII.GetBytes(key);
if (!Certificate.HasPrivateKey)
throw new Exception("x509 certificate does not contain a private key for decryption");
using (var rsa = Certificate.GetRSAPrivateKey())
{
var result = rsa.Encrypt(bytes, RSAEncryptionPadding.OaepSHA512);
return Convert.ToBase64String(result);
}
}
/// <summary>
/// Returns a X509Certificate2 with the given name
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
protected X509Certificate2 GetX509Certificate(string name)
{
// Get the certificate store for the current user.
var store = new X509Store(StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadOnly);
// Place all certificates in an X509Certificate2Collection object.
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
var signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, name, false);
if (signingCert.Count == 0)
return null;
return signingCert[0];
}
finally
{
store.Close();
}
}
Exception : Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Access denied'
Here is the stack:
at System.Security.Cryptography.RSACng.EncryptOrDecrypt(SafeNCryptKeyHandle key, Byte[] input, AsymmetricPaddingMode paddingMode, Void* paddingInfo, EncryptOrDecryptAction encryptOrDecrypt)
at System.Security.Cryptography.RSACng.EncryptOrDecrypt(Byte[] data, RSAEncryptionPadding padding, EncryptOrDecryptAction encryptOrDecrypt)
at System.Security.Cryptography.RSACng.Decrypt(Byte[] data, RSAEncryptionPadding padding)
at VmeApi.Extensions.KeyEncryptService.DecryptKey(String key) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Extensions\AppSettings\KeyEncryptService.cs:line 69
at VmeApi.Extensions.KeyEncryptService..ctor(String certName, String encryptedKey) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Extensions\AppSettings\KeyEncryptService.cs:line 31
at Management_Core_Api.Startup.ConfigureServices(IServiceCollection services) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Startup.cs:line 83
I have tried giving my account, IUser Account and network service full access to the certificate's private key using mmc and restarting the OS but that didn't do anything.