Home > Software design >  Can't extract private key from PCKS#12 encoded certificate file in .NET 6
Can't extract private key from PCKS#12 encoded certificate file in .NET 6

Time:07-30

I'm writing a .NET 6 application for Windows that is intended to extract the private key from a PFX file containing an RSA cert/key bundle.

public static Boolean ToCertAndKey(String pfxFilePath, String? unlockPassword, String certFilePath, String keyFilePath, String? keyPassword, out String error) {
    try {
      error = String.Empty;
      using var bundle = new X509Certificate2(pfxFilePath, unlockPassword);
      RSA key = bundle.GetRSAPrivateKey();

      Byte[] publicKeyBytes = key.ExportSubjectPublicKeyInfo();
      Byte[] privateKeyBytes;

      //We fail here.
      if (String.IsNullOrEmpty(keyPassword)) {
        privateKeyBytes = key.ExportPkcs8PrivateKey();
      } else {
        privateKeyBytes = key.ExportEncryptedPkcs8PrivateKey(keyPassword,
          new PbeParameters(
            PbeEncryptionAlgorithm.Aes256Cbc,
            HashAlgorithmName.SHA256,
            iterationCount: 1));
      }

      String encodedCert = new(PemEncoding.Write("PUBLIC KEY", publicKeyBytes));
      File.WriteAllText(certFilePath, encodedCert);
      String encodedKey = new(PemEncoding.Write("PRIVATE KEY", privateKeyBytes));
      File.WriteAllText(keyFilePath, encodedKey);
      return true;
    } catch (Exception ex) {
      error = $"An exception occurred: '{ex.Message}'\r\n\r\nStack Trace:\r\n{ex.StackTrace}";

      return false;
    }
}

It fails at both ExportPkcs8PrivateKey (When I don't specify a password to encrypt the key) and ExportEncryptedPkcs8PrivateKey (when I do) with the same exception text:

WindowsCryptographicException: The requested operation is not supported

I came across this answer however, I'm still receiving the same exception at RSA.ExportEncryptedPkcs8PrivateKey.

There doesn't appear to be anything wrong with the PFX files I've been testing with; I'm able to import them into my certstore via the UI or PowerShell with no issues.

Hoping someone else has run into this issue.

CodePudding user response:

You need to mark the keys as exportable.

Change

using var bundle = new X509Certificate2(pfxFilePath, unlockPassword);

to

using var bundle = new X509Certificate2(pfxFilePath, unlockPassword, X509KeyStorageFlags.Exportable);
  • Related