0

I'm trying to extract a private key from a .PFX file to a .PEM file format. I was able to do it using Aes128Cbc in either .NET or OpenSSL:

.NET:

PbeParameters pbeParams = new PbeParameters(PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA256, 1);
byte[] privateKey = rsaPrivateKey.ExportEncryptedPkcs8PrivateKey("pass123", pbeParams);

Console.WriteLine("Generating PEM file...\n"); StringWriter stringWriter = new StringWriter(); PemObject pemObject = new PemObject("ENCRYPTED PRIVATE KEY", privateKey); Pem.PemWriter pemWriter = new PemWriter(stringWriter); pemWriter.WriteObject(pemObject);

OpenSSL:

openssl pkcs12 -in path/to/pfx -nocerts -out path/to/output

For both output options, I could check the key by using:

openssl rsa -check -noout -in private-key.pem

Now, I'm trying to change the Password-Based Encryption algorithm to use AES-GCM but I don't know how to do it or even if it is possible. I've tried to use AesGcm on .NET and also searched into the options of openssl pkcs12 command but I couldn't find a way to do it:

byte[] privateKeyBytes = rsaPrivateKey.ExportPkcs8PrivateKey();

byte[] salt = GenerateRandomBytes(16); byte[] iv = GenerateRandomBytes(12); int iterations = 100_000; int keySize = 256; int tagSize = 128 / 8;

byte[] key = DeriveKey("pass123", salt, iterations, keySize);

byte[] encryptedData, tag; using (AesGcm aesGcm = new AesGcm(key)) { encryptedData = new byte[privateKeyBytes.Length]; tag = new byte[tagSize]; aesGcm.Encrypt(iv, privateKeyBytes, encryptedData, tag); }

StringWriter stringWriter = new StringWriter(); PemObject pemObject = new PemObject("ENCRYPTED PRIVATE KEY", encryptedData); PemWriter pemWriter = new PemWriter(stringWriter); pemWriter.WriteObject(pemObject);

// ...

public static byte[] GenerateRandomBytes(int length) { byte[] randomBytes = new byte[length]; using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { rng.GetBytes(randomBytes); } return randomBytes; }

public static byte[] DeriveKey(string password, byte[] salt, int iterations, int keySize) { using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations)) { return pbkdf2.GetBytes(keySize / 8); } }

I had also tried to concatenate all info into the PEM file:

Array.Copy(pemData, salt, 16);
Array.Copy(pemData, 16, iv, 0, 12);
Array.Copy(pemData, 28, encryptedData, 0, privateKeyBytes.Length);
Array.Copy(pemData, 28 + privateKeyBytes.Length, tag, 0, tagSize);

I don't much understand about all PKCS standards but after reading about PKCS #12 and after looking for some answers among the internet I'm wondering if it's possible to do it or if there is some kind of impossibility that I couldn't see yet.

0 Answers0