{"record":{"id":"5b4606e885d84581","repo":"dotnet/wpf","slug":"sr-digsigcannotlocatecertificate","errorCode":null,"errorMessage":"SR.DigSigCannotLocateCertificate","messagePattern":"SR\\.DigSigCannotLocateCertificate","errorType":"exception","errorClass":"CryptographicException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs","lineNumber":1137,"sourceCode":"            // look for appropriate certificates\n            X509Store store = new X509Store(StoreLocation.CurrentUser);\n\n            try\n            {\n                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);\n\n                X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;\n\n                collection = collection.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true);\n                if (collection.Count > 0)\n                {\n                    if (collection.Count > 1)\n                        throw new CryptographicException(SR.DigSigDuplicateCertificate);\n\n                    signer = collection[0];\n                }\n                else\n                    throw new CryptographicException(SR.DigSigCannotLocateCertificate);\n            }\n            finally\n            {\n                store.Close();\n            }\n\n            // get the corresponding AsymmetricAlgorithm\n            return GetPrivateKey(signer);\n        }\n\n\n        /// <summary>\n        /// This method validated the Reference tags as per the restrictions imposed\n        /// by the OPC spec.\n        /// NOTE: The same method is called from Verify and Sign methods. At verify time we need to make sure\n        /// that there is exactly one Package-specific reference. At Sign time we need to make sure that\n        /// there are no package-specific references in the list of references passed to Sign APIs as a \n        /// input parameter, since we will be generating Package-specific object.","sourceCodeStart":1119,"sourceCodeEnd":1155,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs#L1119-L1155","documentation":"GetPrivateKeyForSigning looks up the signer certificate by thumbprint in the certificate store when the provided X509Certificate2 lacks an accessible private key. If no matching certificate with a private key is found, CryptographicException(SR.DigSigCannotLocateCertificate) is thrown.","triggerScenarios":"Calling PackageDigitalSignatureManager.Sign with a certificate loaded without its private key (e.g. from a .cer file or a PFX imported without the key), and no cert with that thumbprint plus a private key exists in the personal store.","commonSituations":"Deploying only the public certificate to servers; PFX password lost so the key was never imported; certificates on smart cards not reachable from the process account; app pool identities lacking access to the key (though that often surfaces as a different access error).","solutions":["Install the certificate with its private key (import the PFX into CurrentUser\\My via certmgr or Import-PfxCertificate).","Pass an X509Certificate2 instance that already has PrivateKey set so the store lookup is skipped.","Verify the private key exists: check cert.HasPrivateKey before signing.","If the key is on a smart card/HSM, ensure the CSP/KSP is installed and the token is accessible to the running user."],"exampleFix":"// before: public-only cert\nX509Certificate2 cert = new X509Certificate2(\"signer.cer\");\ndsm.Sign(toSign, cert); // throws\n// after: load PFX with private key\nX509Certificate2 cert = new X509Certificate2(\"signer.pfx\", pfxPassword, X509KeyStorageFlags.MachineKeySet);\ndsm.Sign(toSign, cert);","handlingStrategy":"validation","validationCode":"bool canSign = signer != null && signer.HasPrivateKey;\nif (!canSign)\n{\n    using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);\n    store.Open(OpenFlags.ReadOnly);\n    canSign = store.Certificates.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true)\n               .Count > 0;\n}","typeGuard":"static bool PrivateKeyResolvable(X509Certificate2 c) =>\n    c != null && (c.HasPrivateKey ||\n    (new X509Store(StoreName.My, StoreLocation.CurrentUser) is var s) && false); // prefer explicit store check in caller code","tryCatchPattern":"try { dsm.Sign(toSign, cert); }\ncatch (CryptographicException ex) when (ex.Message.Contains(\"Locate\"))\n{ /* private key not installed — prompt user to import PFX */ }","preventionTips":["Always check cert.HasPrivateKey before signing.","Import PFX (not .cer) files when a signing key is required.","Ensure the running account can access the key's CSP/KSP.","Keep smart-card tokens connected and drivers installed."],"tags":["wpf","cryptography","certificate","private-key","store"],"backgroundTag":"certificate-not-found","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}