繁体   English   中英

X509Store 证书问题。查找 FindByThumbprint

[英]Problems with X509Store Certificates.Find FindByThumbprint

我在使用方法X509Store.Certificates.Find时遇到问题

public static X509Certificate2 FromStore(StoreName storeName, 
          StoreLocation storeLocation, X509FindType findType, string findValue)
{
    X509Store store = new X509Store(storeName, storeLocation);
    store.Open(OpenFlags.ReadOnly);
    try
    {
        //findValue = "7a6fa503ab57b81d6318a51ca265e739a51ce660"
        var results = store.Certificates.Find(findType, findValue, true);

        return results[0];                
    }
    finally
    {
        store.Close();
    }
}

在这种情况下, Find Method 返回 0 个结果( results.Count == 0 ),但如果我将 findValue 作为常量,则该方法会找到证书。

public static X509Certificate2 FromStore(StoreName storeName, 
           StoreLocation storeLocation, X509FindType findType, string findValue)
{
    X509Store store = new X509Store(storeName, storeLocation);
    store.Open(OpenFlags.ReadOnly);
    try
    {         
        //findValue= "7a6fa503ab57b81d6318a51ca265e739a51ce660"
        var results = store.Certificates.Find(findType, 
                              "7a6fa503ab57b81d6318a51ca265e739a51ce660", true);
        return results[0];
    }
    finally
    {
        store.Close();
    }
}

我想您已经将 Windows 证书信息对话框中的指纹复制粘贴到您的代码中(如果这是一个简化示例,则复制粘贴到配置文件中)。 令人讨厌的是,指纹文本框中的第一个字符是不可见的 Unicode“从左到右标记”控制字符 尝试选择开头的字符串引号和指纹的第一个字符,删除它们(这也将去除中间的不可见字符),然后手动重新键入它们。


今天我自己也遇到了这种奇怪的行为,我花了一个多小时才弄明白。 我最终看到它的方法是使用调试器检查证书对象的findValueThumbprint的长度和哈希码,结果是不同的。 这让我在调试器中检查了这些字符串的字符数组,其中出现了不可见字符。

我在这里接受了一些答案,并将它们组合成一个静态方法,该方法负责删除所有特殊字符和大写字母。 希望其他人可以使用它。

public static X509Certificate2 GetCertificate(string thumbprint)
{
    // strip any non-hexadecimal values and make uppercase
    thumbprint = Regex.Replace(thumbprint, @"[^\da-fA-F]", string.Empty).ToUpper();
    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

    try
    {
        store.Open(OpenFlags.ReadOnly);

        var certCollection = store.Certificates;
        var signingCert = certCollection.Find(X509FindType.FindByThumbprint, thumbprint, false);
        if (signingCert.Count == 0)
        {
            throw new FileNotFoundException(string.Format("Cert with thumbprint: '{0}' not found in local machine cert store.", thumbprint));
        }

        return signingCert[0];
    }
    finally
    {
        store.Close();
    }
}

我遇到了同样的问题并解决了它:

  1. 我将指纹从 mmc 直接复制到 VS。 我比较了字符串,没有发现任何区别。

  2. 用 hash.length 检查长度,有区别,41 对 40。

通过将其从 mmc 中复制出来,在字符串中添加了一个不可见的 Char。


解决:

  1. 将指纹从 mmc 复制到 Notepad.exe
  2. 再次复制这个字符串
  3. 粘贴到您的代码

它正在工作。

我成了这个的受害者。 Windows 控制台管理单元中不仅有一个 Unicode“从左到右”字符,而且还有小写的十六进制字符,每两个字符之间有空格。 CertUtil 的输出也有小写字符和空格。 为了获得匹配,我必须将 findValue 指定为已转换为的字符串

  1. 删除前导特殊字符,
  2. 删除字符簇之间的空格,
  3. 将所有字符更改为大写

这也让我感到困惑,我编写了这个函数来在从 MMC 复制和粘贴时清除指纹:

public string CleanThumbprint(string mmcThumbprint)
    {
        //replace spaces, non word chars and convert to uppercase
        return Regex.Replace(mmcThumbprint, @"\s|\W", "").ToUpper();
    }

...
        var myThumbprint = CleanThumbprint("‎b3 ab 84 e5 1e e5 e4 75 e7 a5 3e 27 8c 87 9d 2f 05 02 27 56");
        var myCertificate = certificates.Find(X509FindType.FindByThumbprint, myThumbprint, true)[0];

这段代码应该可以工作。

我想你已经从证书管理控制台复制了这个指纹。 并且该复制的值包含在 Visual Studio 中不可见的 unicode 不可读符号。 尝试删除第一个不可见符号,如果这是我的想法,这应该可行。

我遇到了同样的事情。 我在这里的任何地方都找不到这个答案,所以我会发布它。 对我来说,X509Store 查找功能似乎无法正常工作。 我通过一个简单的 for 循环并手动检索证书来验证这一点。

  X509Store store = new X509Store(StoreName.Root,StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate cert = new X509Certificate();
        for (int i = 0; i < store.Certificates.Count; i++)
        {
            if (store.Certificates[i].SerialNumber == "XXXX")
            {
                cert = store.Certificates[i];
            }
        }

这是上述建议的简单代码版本-当然对我有用

 private X509Certificate2 GetCertificate()
    {
        var certStore = new X509Store("my");
        certStore.Open(OpenFlags.ReadOnly);
        try
        {
            const string thumbprint = "18 33 fe 3a 67 d1 9e 0d f6 1e e5 d5 58 aa 8a 97 8c c4 d8 c3";
            var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint,
            Regex.Replace(thumbprint, @"\s+", "").ToUpper(), false);
            if (certCollection.Count > 0)
                return certCollection[0];
        }
        finally
        {
            certStore.Close();
        }
        return null;
    }

我也遇到了这个不可见的 Unicode 字符。 尝试使用记事本(Windows 10)不知何故对我来说也不起作用。 最后,我使用 PowerShell 获取干净的指纹十六进制:

PS C:\> $tp= (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "mycert"}).Thumbprint;
PS C:\> $tp

Unicode 字符就这么多。

替换代码以在商店中找到您的证书,如下所示:

var results = store.Certificates.Find(findType, findValue, true); 

还有第三个参数是 bool 仅当证书有效时才返回证书。 因此,请确保您的证书有效。 如果您有自签名证书左右,则只需将第三个参数传递为“false”

只是为了让您知道隐形字符是什么,我看到 mmc 中的指纹是:75 3a ...

然后我将它复制并粘贴到我的 vim 中,我看到以下内容:

<200e>75 3a ...

所以在你去掉第一个字符“<200e>”和多余的空格后,你会没事的。

Aasmund Eldhuset 的回答(和其他答案)+1。

令人讨厌的是,指纹文本框中的第一个字符是不可见的 Unicode“从左到右标记”控制字符。

很难验证它是否存在。 例如,将指纹从我的配置文件复制到 VS 二进制编辑器有时会得到不可见的字符,有时不会。

此代码也未能显示问题。 我逐步浏览代码并将鼠标悬停在 x509Store 上以找到我想要的证书。

                X509Certificate2 cert2 = null;
                string storeName = StoreName.My.ToString();
                var x509Store = new X509Store(storeName, StoreLocation.LocalMachine);
                x509Store.Open(OpenFlags.ReadOnly);

                var cert3 = x509Store.Certificates[4];
                var thumbprint3 = cert3.Thumbprint;
                int gotIt = thumbprint3.CompareTo(clientCert);

经过长时间的分析,这对我有用。

  1. 将指纹从证书复制到记事本。
  2. 将拇指印从记事本复制到 Visual Studio。
  3. 以管理员身份运行 Visual Studio。

这就像一个魅力。

var results = store.Certificates.Find(findType, findType, true);

我认为你的意思是第二个参数是“findValue”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM