简体   繁体   English

X509Store 证书问题。查找 FindByThumbprint

[英]Problems with X509Store Certificates.Find FindByThumbprint

I'm having a problem when I use the method X509Store.Certificates.Find我在使用方法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();
    }
}

In this case the Find Method returns 0 results ( results.Count == 0 ), but if I put the findValue as constant the method find the certificate.在这种情况下, 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();
    }
}

I suppose that you have copy-pasted the thumbprint from the Windows certificate information dialog box into your code (or to a config file if this is a simplified example).我想您已经将 Windows 证书信息对话框中的指纹复制粘贴到您的代码中(如果这是一个简化示例,则复制粘贴到配置文件中)。 Annoyingly, the first character in the thumbprint textbox is the invisible Unicode "left-to-right-mark" control character .令人讨厌的是,指纹文本框中的第一个字符是不可见的 Unicode“从左到右标记”控制字符 Try selecting the opening string quote and the first character of the thumbprint, deleting them (which will also get rid of the invisible character in-between), and retyping them by hand.尝试选择开头的字符串引号和指纹的第一个字符,删除它们(这也将去除中间的不可见字符),然后手动重新键入它们。


I was subjected to this odd behaviour myself today, and it took me over an hour to figure it out.今天我自己也遇到了这种奇怪的行为,我花了一个多小时才弄明白。 The way I finally saw it was by using the debugger to check the lengths and hash codes of findValue and of the Thumbprint of the certificate object, which turned out to be different.我最终看到它的方法是使用调试器检查证书对象的findValueThumbprint的长度和哈希码,结果是不同的。 This led me to inspect the character arrays of those strings in the debugger, where the invisible character showed up.这让我在调试器中检查了这些字符串的字符数组,其中出现了不可见字符。

I took some of the answers here and combined them into a static method that takes care of removing special characters and upper cases everything.我在这里接受了一些答案,并将它们组合成一个静态方法,该方法负责删除所有特殊字符和大写字母。 Hopefully someone else can use it.希望其他人可以使用它。

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();
    }
}

I had the same Problem and solved it:我遇到了同样的问题并解决了它:

  1. I copied the Fingerprint from mmc directly to VS.我将指纹从 mmc 直接复制到 VS。 I compared the strings and didn't find any difference.我比较了字符串,没有发现任何区别。

  2. Checking the length with hash.length, there was a difference, 41 vs. 40.用 hash.length 检查长度,有区别,41 对 40。

There is an invisible Char added to the string by copying it out of mmc.通过将其从 mmc 中复制出来,在字符串中添加了一个不可见的 Char。


Solving:解决:

  1. copy the Fingerprint from mmc to Notepad.exe将指纹从 mmc 复制到 Notepad.exe
  2. copy this string again再次复制这个字符串
  3. paste to your code粘贴到您的代码

It's working.它正在工作。

I fell victim to this.我成了这个的受害者。 Not only was there a Unicode "left-to-right" character in the Windows console snap-in display of the thumbprint, but it also had lowercase hex characters, with spaces between every two characters. Windows 控制台管理单元中不仅有一个 Unicode“从左到右”字符,而且还有小写的十六进制字符,每两个字符之间有空格。 The output of CertUtil also had lowercase characters, and spaces. CertUtil 的输出也有小写字符和空格。 To get a match, I had to specify the findValue as a string which has been transformed to为了获得匹配,我必须将 findValue 指定为已转换为的字符串

  1. Remove the leading special character,删除前导特殊字符,
  2. Remove the whitespace between character clusters,删除字符簇之间的空格,
  3. Change all the characters to uppercase .将所有字符更改为大写

This tripped me up too, I wrote this function to clean the thumbprint when copied and pasted from MMC:这也让我感到困惑,我编写了这个函数来在从 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];

This code should work.这段代码应该可以工作。

I suppose you have copied this thumbprint from the certificate management console.我想你已经从证书管理控制台复制了这个指纹。 And that copied value contains unicode non-readable symbol which is invisible in Visual Studio.并且该复制的值包含在 Visual Studio 中不可见的 unicode 不可读符号。 Try to delete the first invisible symbol and if this is what I think of, this should work.尝试删除第一个不可见符号,如果这是我的想法,这应该可行。

I ran into this same thing.我遇到了同样的事情。 I couldn't find this answer anywhere in here so I'll post it.我在这里的任何地方都找不到这个答案,所以我会发布它。 It seems for me the X509Store find function just was flat not working.对我来说,X509Store 查找功能似乎无法正常工作。 I verified this by a simple for loop and retrieving the cert manually.我通过一个简单的 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];
            }
        }

Here is the simple version of code for the above suggestions- ofcourse which is worked for me这是上述建议的简单代码版本-当然对我有用

 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;
    }

I encounter this invisible Unicode char as well.我也遇到了这个不可见的 Unicode 字符。 Trying using Notepad (Windows 10) somehow didn't work well for me either.尝试使用记事本(Windows 10)不知何故对我来说也不起作用。 Finally, I use PowerShell to get the clean thumbprint hex:最后,我使用 PowerShell 获取干净的指纹十六进制:

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

SO much for Unicode char. Unicode 字符就这么多。

Replace the code to find your certificate in the store as below:替换代码以在商店中找到您的证书,如下所示:

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

Also the 3rd param which is bool return certificates only if the certificate is valid.还有第三个参数是 bool 仅当证书有效时才返回证书。 So make sure that your certificate is valid.因此,请确保您的证书有效。 If you have a self signed certificate or so then just pass the 3rd param to be "false"如果您有自签名证书左右,则只需将第三个参数传递为“false”

Just to let you know what the invisible character is, I see the thumbprint in the mmc being: 75 3a ...只是为了让您知道隐形字符是什么,我看到 mmc 中的指纹是:75 3a ...

Then I copy and paste it in my vim, I see the following:然后我将它复制并粘贴到我的 vim 中,我看到以下内容:

<200e>75 3a ... <200e>75 3a ...

So after you get rid of the first char "<200e>" and the extra spaces, you'll be fine.所以在你去掉第一个字符“<200e>”和多余的空格后,你会没事的。

+1 for Aasmund Eldhuset's answer (and other answers). Aasmund Eldhuset 的回答(和其他答案)+1。

Annoyingly, the first character in the thumbprint textbox is the invisible Unicode "left-to-right-mark" control character.令人讨厌的是,指纹文本框中的第一个字符是不可见的 Unicode“从左到右标记”控制字符。

It can be hard to verify that it is present.很难验证它是否存在。 For example, copying the thumbprint from my config file to the VS binary editor sometimes gets the invisible character and sometimes doesn't.例如,将指纹从我的配置文件复制到 VS 二进制编辑器有时会得到不可见的字符,有时不会。

Also this code failed to show a problem.此代码也未能显示问题。 I stepped through the code and moused over the x509Store to find the cert I wanted.我逐步浏览代码并将鼠标悬停在 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);

After long analysis, Here is what worked for me.经过长时间的分析,这对我有用。

  1. Copy the thumb print from certificate to notepad.将指纹从证书复制到记事本。
  2. Copy the thumb print from notepad to visual studio.将拇指印从记事本复制到 Visual Studio。
  3. Run visual studio as admin.以管理员身份运行 Visual Studio。

This works like a charm.这就像一个魅力。

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

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

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

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