{"record":{"id":"efd18fdc4c622b4e","repo":"dotnet/wpf","slug":"sr-digsigduplicatecertificate","errorCode":null,"errorMessage":"SR.DigSigDuplicateCertificate","messagePattern":"SR\\.DigSigDuplicateCertificate","errorType":"exception","errorClass":"CryptographicException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs","lineNumber":1132,"sourceCode":"        private static AsymmetricAlgorithm GetPrivateKeyForSigning(X509Certificate2 signer)\n        {\n            // if the certificate does not actually contain the key, we need to look it up via ThumbPrint\n            Invariant.Assert(!signer.HasPrivateKey);\n\n            // 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","sourceCodeStart":1114,"sourceCodeEnd":1150,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs#L1114-L1150","documentation":"GetPrivateKeyForSigning, when given only a certificate without an accessible private key, searches the personal certificate store by thumbprint for a matching cert with a private key. If more than one certificate with that thumbprint is found, CryptographicException(SR.DigSigDuplicateCertificate) is thrown, because the correct private key cannot be determined unambiguously.","triggerScenarios":"Calling PackageDigitalSignatureManager.Sign with an X509Certificate2 whose private key is not available, while the CurrentUser/LocalMachine store contains two certs with identical thumbprints (e.g. the same certificate installed in more than one store).","commonSituations":"The same certificate imported into both CurrentUser\\My and LocalMachine\\My; roaming profiles duplicating store entries; certificate re-import after renewal leaving stale duplicates.","solutions":["Remove the duplicate certificate so only one copy with that thumbprint remains (certmgr.msc → delete the redundant entry).","Pass a certificate instance whose PrivateKey is already available so the store lookup is skipped.","Narrow the store selection by opening only one store location when resolving the signer.","Rebuild a clean certificate store on the affected machine and re-import the certificate once."],"exampleFix":"// before: resolves via store, duplicates present\ndsm.Sign(toSign, publicOnlyCert);\n// after: supply cert with private key\nX509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);\nstore.Open(OpenFlags.ReadOnly);\nX509Certificate2 cert = store.Certificates.Find(X509FindType.FindByThumbprint, thumb, true)[0];\ndsm.Sign(toSign, cert);","handlingStrategy":"try-catch","validationCode":"using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);\nstore.Open(OpenFlags.ReadOnly);\nint dup = store.Certificates.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true).Count;\nbool ok = dup == 1;","typeGuard":"static bool SingleStoreMatch(X509Certificate2 c) {\n    using var s = new X509Store(StoreName.My, StoreLocation.CurrentUser);\n    s.Open(OpenFlags.ReadOnly);\n    return s.Certificates.Find(X509FindType.FindByThumbprint, c.Thumbprint, true).Count == 1;\n}","tryCatchPattern":"try { dsm.Sign(toSign, cert); }\ncatch (CryptographicException ex) when (ex.Message.Contains(\"Duplicate\"))\n{ /* dedupe store and retry once */ }","preventionTips":["Keep one copy of each certificate per store location.","Pass certificates that already carry their private key.","Periodically audit certificate stores for duplicates.","Avoid re-importing the same PFX repeatedly."],"tags":["wpf","cryptography","certificate-store","duplicate"],"backgroundTag":"duplicate-certificate","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"}