当前位置: 首页 > 知识库问答 >
问题:

如何确保X509Certificate2类不返回重复的签名证书?

岳安福
2023-03-14

我有一个C#windows窗体应用程序。用户键入message、subject、to,并从下拉列表中选择签名证书,以使用X509Certificate2类对电子邮件进行签名。

下面是如何填充下拉列表(组合框SigningCertList)的代码段:

try
{
    X509Certificate2[] certs;
    certs = CryptoHelper.GetSigningCertificateList();
    SigningCertList.Items.AddRange(certs);
    SigningCertList.ValueMember = "SerialNumber";
    SigningCertList.DisplayMember = "FriendlyName";
    SigningCertList.SelectedIndexChanged += new System.EventHandler(SigningCertList_SelectedIndexChanged);
    SigningCertList.SelectedItem = 0;
}

症状很奇怪。组合框将显示我的签名证书(从p12文件安装)。但是,如果我加载Windows证书MMC快照,我在搜索时找不到它。重新安装证书后,我在Windows证书MMC快照中看到它,现在在下拉列表中复制。列表中只有第二个(或最后一个/最近的)签名证书实际对其进行签名。

那么,如何确保X509Certificate2类不返回重复的签名证书呢?

下面是GetSigningCertificateList()方法:` public static X509Certificate2[]GetSigningCertificateList(){var list=new list();

        int matches = 0;
        X509Store localStore = new X509Store(StoreLocation.LocalMachine);
        localStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        try
        {
            foreach (X509Certificate2 cert in localStore.Certificates)
                {
                    foreach (X509Extension extension in cert.Extensions)
                    {
                        X509KeyUsageExtension usageExtension = extension as X509KeyUsageExtension;

                        if (usageExtension != null)
                        {
                            bool matchesUsageRequirements = ((X509KeyUsageFlags.DigitalSignature & usageExtension.KeyUsages) == X509KeyUsageFlags.DigitalSignature);

                            if (matchesUsageRequirements)
                            {
                                list.Add(cert);
                                matches += 1;
                            }
                        }
                    }
                }
        }
        finally
        {
            localStore.Close();
        }

        X509Store userStore = new X509Store(StoreLocation.CurrentUser);
        userStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        try
        {
            foreach (X509Certificate2 cert in userStore.Certificates)
            {
                foreach (X509Extension extension in cert.Extensions)
                {
                    X509KeyUsageExtension usageExtension = extension as X509KeyUsageExtension;

                    if (usageExtension != null)
                    {
                        bool matchesUsageRequirements = ((X509KeyUsageFlags.DigitalSignature & usageExtension.KeyUsages) == X509KeyUsageFlags.DigitalSignature);

                        if ((matchesUsageRequirements) && cert.FriendlyName.IndexOf("MYcompanyname.",0) >= 0)
                        {
                            list.Add(cert);
                            matches += 1;
                        }
                    }
                }
            }
        }
        finally
        {
            userStore.Close();
        }

        return list.ToArray();
    }

}`

共有1个答案

彭展
2023-03-14

您提到您在MMC中看不到证书,但在您的应用程序中看到了;当您通过MMC安装证书时,它会显示两次。这表明您正在使用MMC查看用户我的商店(或计算机我的商店),但有问题的证书通常存在于另一个位置。

一旦证书在两个不同的商店注册(相同的商店名称,不同的位置=

您可以通过标准的重复数据消除策略来防止重复,例如使用哈希集

所以简单的dedup是替换list=new List

哈希集只保留第一个冲突;所以,如果你想让LocalMachine成为首选,你已经做到了。如果CurrentUser赢了,您可能需要切换块。

另外两件值得注意的事情:

>

  • 如果证书根本没有密钥使用扩展,则认为它对所有使用都有效。你的代码没有做到这一点。(如果您知道应用程序中的“正确”证书总是正确的,那么就没有问题了)

    X509商店。证书每次调用都返回新对象;您可以通过对未返回的证书调用Dispose(或对.NET 4.5.2及以下版本重置)来减少终结。

  •  类似资料:
    • line.FlatMap(WordSutil::GetWords)是方法引用中错误的返回类型: 编码方法:

    • 我想使用此函数返回s的列表,但当以这种方式设置时,我会收到未选中的分配警告,因为返回的列表未指定包含s。这会导致生成失败。 尝试在返回语句中转换,但随后我得到一个未检查的转换警告 尝试指定列表类型时声明,但然后我还必须指定响应类型参数(-

    • > 文件,将ZIP文件的内容描述为XML(文件); 包含传输文档内容的文件(例如,文件); 具有分离数字签名内容的文件(文件-分离数字签名); > 方法(请参阅下面的此方法)当前未使用文件的分离签名。我确实试过了,但没有成功。如何正确验证文件对应文件的分离签名? 在方法(请参阅下面的方法)中,如何验证从文件中提取的证书与从Base64格式的输入字符串中提取的证书的一致性? 代码行-->Certif

    • 我有一个匿名函数,如下所示: 我想指定cb必须返回一个布尔值,但我是一个打字稿新手,不知道我是否可以(或者即使我这样做或不这样做会对解析器产生影响)。 我该怎么做?

    • 但是同时使用不同签名和不同返回类型的重载方法有什么问题呢?为什么这会产生错误?

    • 我将这个字符串从客户端发送到服务器: 该字符串是由服务器打印出来的,所以它是正确的。 “AR”是数据包名称,值是弓箭手将要射出的箭的速度。 这里出什么问题了?