dotnet/wpf · error · ArgumentException

SR.CertificateKeyTypeNotSupported

Error message

SR.CertificateKeyTypeNotSupported

What it means

GenerateKeyInfo builds the KeyInfo section for a new signature and supports only RSA and DSA asymmetric keys. If the supplied key is neither, ArgumentException(SR.CertificateKeyTypeNotSupported) is thrown, because the signer certificate's private key algorithm cannot be represented as KeyInfo key values.

Solutions

  1. Sign with a certificate whose private key is RSA (or DSA); issue or export an RSA-based certificate from your CA.
  2. Check the key algorithm before signing: cert.GetKeyAlgorithm() / key is RSA.
  3. Use an alternative signing stack (e.g. .NET's SignXml with supported providers or an OPC-compliant third-party signer) that supports the key type.
  4. If the certificate lives on a smart card, re-issue it as RSA for use with WPF packaging signatures.

Example fix

// before: ECDSA cert fails
X509Certificate2 cert = GetEcdsaCert();
dsm.Sign(toSign, cert); // throws
// after: ensure RSA
if (cert.GetKeyAlgorithm() != "1.2.840.113549.1.1.1") // RSA OID
    cert = GetRsaCert();
dsm.Sign(toSign, cert);
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard before Sign
static bool IsSupportedSigner(X509Certificate2 cert) =>
    cert != null && cert.HasPrivateKey &&
    (cert.PrivateKey is RSA || cert.PrivateKey is DSA);
// or: cert.GetKeyAlgorithm() == "1.2.840.113549.1.1.1" (RSA)

Type guard

static bool IsRsaOrDsa(X509Certificate2 c) =>
    c?.PrivateKey is RSA || c?.PrivateKey is DSA;

Try / catch

try { dsm.Sign(toSign, cert); }
catch (ArgumentException ex) when (ex.ParamName == "signer")
{ /* unsupported key algorithm — provision an RSA certificate */ }

Prevention

When it happens

Trigger: Calling PackageDigitalSignatureManager.Sign with a certificate whose private key is not RSA or DSA — e.g. ECDSA (EC) or other modern algorithm certificates on newer Windows/SmartCard/HSM stores.

Common situations: Using a PFX or store certificate with an EC private key; hardware tokens issuing ECC keys; .NET Core/5+ environments where ECDSA certificates are common but this WPF path only handles RSA/DSA.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/c74f1ed36a70056b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs:1080

        private KeyInfo GenerateKeyInfo(AsymmetricAlgorithm key, X509Certificate2 signer)
        {
            // KeyInfo section
            KeyInfo keyInfo = new KeyInfo();
            KeyInfoName keyInfoName = new KeyInfoName
            {
                Value = signer.Subject
            };
            keyInfo.AddClause(keyInfoName);               // human readable Principal name

            // Include the public key information (if we are familiar with the algorithm type)
            if (key is RSA)
                keyInfo.AddClause(new RSAKeyValue((RSA)key));    // RSA key parameters
            else
            {
                if (key is DSA)
                    keyInfo.AddClause(new DSAKeyValue((DSA)key));    // DSA
                else
                    throw new ArgumentException(SR.CertificateKeyTypeNotSupported, nameof(signer));
            }

            // the actual X509 cert
            keyInfo.AddClause(new KeyInfoX509Data(signer));

            return keyInfo;
        }

        private DataObject GenerateObjectTag(
                HashAlgorithm hashAlgorithm,
                IEnumerable<Uri> parts, IEnumerable<System.IO.Packaging.PackageRelationshipSelector> relationshipSelectors,
                String signatureId)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.AppendChild(xDoc.CreateNode(XmlNodeType.Element, "root", "namespace")); // dummy root
            xDoc.DocumentElement.AppendChild(XmlSignatureManifest.GenerateManifest(_manager, xDoc, hashAlgorithm, parts, relationshipSelectors));
            xDoc.DocumentElement.AppendChild(XmlSignatureProperties.AssembleSignatureProperties(xDoc, DateTime.Now, _manager.TimeFormat, signatureId));

View on GitHub (pinned to 81131a70a4)