Barvna shema: Temna
Trenutno dejavna stran: start » en » Documentation » Post-Quantum Cryptography » WKL.System.Security.Cryptography overview » How-to guides » Transfer certificates with PQ keys as PFX files

Transfer certificates with PQ keys as PFX files

You want to move a certificate together with its classical key and its PQ key to another process or machine, for example from the machine that issued it to the server that uses it.

Solution overview

ElementPurpose
ExportPfx(password)writes the certificate, the classical key, and the PQ key to a PKCS #12 file
X509Certificate2ExportExtensions.ImportPfx(bytes, password, flags)reads the file and associates the PQ key again
X509Certificate2Collection.ExportPfx, ImportPfxCollectionthe same for several certificates, for example with a chain
ExportPfx(password, pbeParameters)as above, with encryption settings you choose

Implementation

Export the certificate. Here, server is a certificate whose classical and PQ keys are in the process:

using var serverRsa = RSA.Create(3072);
using var server = new CertificateRequest(
        "CN=www.example.com", serverRsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
    .CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(1), CryptoMode.Hybrid);
 
string password = Convert.ToBase64String(RandomNumberGenerator.GetBytes(24));
File.WriteAllBytes("www.example.com.pfx", server.ExportPfx(password));

Import it in the other process:

using var imported = X509Certificate2ExportExtensions.ImportPfx(
    File.ReadAllBytes("www.example.com.pfx"), password, X509KeyStorageFlags.EphemeralKeySet);
 
using (var pqKey = imported.GetAlternativePrivateMLDsaKey())
{
    Console.WriteLine($"RSA: {imported.HasPrivateKey}, ML-DSA: {pqKey is not null}");
}

For a program that can't read PBES2, write the Triple DES variant explicitly:

var legacy = new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2000);
File.WriteAllBytes("www.example.com-3des.pfx", server.ExportPfx(password, legacy));

Remarks

  • Import with the library. The .NET new X509Certificate2(pfx, password) constructor also reads the file and picks up the certificate and the classical key, but it skips the PQ key. Only ImportPfx associates it.
  • No export without the PQ key. If you explicitly request a PQ export with ExportPfx(password, CryptoMode.Hybrid) and the process doesn't know a PQ key, the method throws a CryptographicException instead of silently writing a file without the PQ key.
  • Pure ML-DSA certificates. For these, the file carries only the ML-DSA key. After the import, GetPrivateMLDsaKey returns the key, and HasPrivateKey stays false.
  • Encryption. Without PbeParameters, ExportPfx with a PQ key encrypts according to PBES2: AES-256-CBC, PBKDF2 with HMAC-SHA-256 and 2,048 iterations, and a SHA-256 MAC. With PbeParameters, you can use Aes128Cbc, Aes192Cbc, or Aes256Cbc with SHA-1, SHA-256, SHA-384, or SHA-512, or TripleDes3KeyPkcs12 with SHA-1. The method rejects other combinations with a CryptographicException. On .NET Framework, the library provides PbeParameters and PbeEncryptionAlgorithm itself, in the System.Security.Cryptography namespace.
  • CryptoMode.Classic. Without PbeParameters, ExportPfx writes exactly the file that the .NET Export(X509ContentType.Pfx, password) method writes, without the PQ key and with the .NET encryption.
  • Protect the password and the file. The file is only as secure as its password. Use a long, random password, send it through a different channel than the file, and delete the file after the import.
  • .NET 8 on Linux. If the certificate's own key is an ML-DSA or ML-KEM key rather than RSA or ECDSA, .NET 8 on Linux can't read the PFX file, and ImportPfx fails there with the .NET CryptographicException. Hybrid certificates aren't affected. On Linux, move such certificates as PEM files, and associate the key with the matching Attach method.
en/wiki/pqcrypt/lib/how-to/export-and-import-pfx.txt · Zadnja sprememba: uporabnika Wolfgang van der Stille