Color scheme: Riviera
You are here: start » en » Documentation » Post-Quantum Cryptography » WKL.System.Security.Cryptography overview » Troubleshooting » The ML-DSA private key is missing

The ML-DSA private key is missing

A call with CryptoMode.Hybrid or CryptoMode.PostQuantum throws a CryptographicException with one of these messages:

The ML-DSA private key of issuer 'CN=Contoso Hybrid CA' is not available.
No ML-DSA private key is available for signer 'CN=Contoso Accounting'; Hybrid signing requires one.
A PQ export was requested, but no ML-DSA private key is available for any certificate.
No ML-DSA key pair is available for 'CN=www.example.com'; a PQ store operation needs one.

Or GetAlternativePrivateMLDsaKey or GetPrivateMLDsaKey returns null.

Environment

All targets. Operations that sign with a certificate's private ML-DSA key are affected: issuing certificates and CRLs, signing CMS messages, exporting PFX files with a PQ key, and storing key files.

Cause

The .NET X509Certificate2 class doesn't carry an ML-DSA key. The library keeps the key in a process table, where the certificate finds it through its thumbprint. The entry is missing in these cases:

  • The certificate was issued in a different process and loaded from a PEM or DER file. Such files don't contain a private key.
  • The certificate was imported with the .NET new X509Certificate2(pfx, password) constructor. That path skips the PQ key in the PFX file.
  • A pure ML-DSA certificate was issued from a request with Create. At first, it only knows the public key.
  • The process restarted. The table lives only as long as the process.

Resolution

Associate the key before you call the operation. How you do that depends on where the key is:

The key isAssociate it with
in a PFX file from ExportPfxX509Certificate2ExportExtensions.ImportPfx instead of the .NET constructor
in a key file next to the certificate storeX509Store.Find(findType, findValue, validOnly, restorePqKeys: true) or X509StoreExtensions.RestorePqKeys
an MLDsaKey in the process, for a hybrid certificatecertificate.AttachAlternativePrivateMLDsaKey(key)
an MLDsaKey in the process, for a pure ML-DSA certificatecertificate.AttachPrivateMLDsaKey(key)

Then check with GetAlternativePrivateMLDsaKey or GetPrivateMLDsaKey that the key is present. The .NET HasPrivateKey property only reflects the classical key. For details, see Keys and key storage.

en/wiki/pqcrypt/lib/troubleshooting/no-ml-dsa-private-key.txt · Last modified: by Wolfgang van der Stille