Search code examples
c#public-key-encryptionx509certificate2elliptic-curvepkcs#7

X509Certificate2 - Access Denied Exception if use ECC certificate


I try to encrypt and decrypt data with System.Security.Cryptography.Pkcs, but it works only with RSA certificates, if I used an ECC (curve ECDH_brainpoolP512r1) certificate the constructor of X509Certificate2 crashes with an Access Denied Exception.

Create SelfSignedCertificate in Powershell

New-SelfSignedCertificate `
 -Subject "CN=Test Code Signing RSA" `
 -Type DocumentEncryptionCert `
 -KeyUsage "DigitalSignature" `
 -FriendlyName "Test Code Signing" `
 -NotAfter (get-date).AddYears(5) `
 -KeyExportPolicy Exportable `
 -SmimeCapabilities ` 
 -KeyAlgorithm ECDH_brainpoolP512r1

Read SelfSignedCertificate in code

var base64cert = "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";
new System.Security.Cryptography.X509Certificates.X509Certificate2(Convert.FromBase64String(base64cert), "qwert");

Exception

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Access Denied
   at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
   at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
   at PkcsEncryption.Program.Certificate(Boolean rsa) in c:\git\PkcsEncryption\PkcsEncryption\Program.cs:line 88
   at PkcsEncryption.Program.Encrypt(Byte[] dataPlain, Boolean useRsa) in c:\git\PkcsEncryption\PkcsEncryption\Program.cs:line 56
   at PkcsEncryption.Program.Main(String[] args) in c:\git\PkcsEncryption\PkcsEncryption\Program.cs:line 22

Solution

  • The PFX which you have encoded as base64 there has internally set the marker indicating it was exported from a machine keystore. Your Access Denied indicates that you are not running as an administrator (and thus do not have the permission to add keys to the machine's keystore).

    To ensure that keys from a PFX get added to the current user's key store set the X509KeyStorageFlags.UserKeySet flag. Or, if you've installed the early access build (or, in the future, the released build) of .NET Framework v4.7.2 you can use EphemeralKeySet to keep the private key in memory and avoid the keystore altogether.

    new System.Security.Cryptography.X509Certificates.X509Certificate2(
        Convert.FromBase64String(base64cert),
        "qwert",
        X509KeyStorageFlags.UserKeySet);