Проблемы с сертификатами X509Store. Найти FindByThumbprint - PullRequest
78 голосов
/ 09 декабря 2011

У меня проблема, когда я использую метод 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();
    }
}

В этом случае метод поиска возвращает 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();
    }
}

Ответы [ 12 ]

122 голосов
/ 21 февраля 2012

Я полагаю, что вы скопировали отпечаток большого пальца из диалогового окна информации о сертификате Windows в ваш код (или в файл конфигурации, если это упрощенный пример). Досадно, что первым символом в текстовом поле отпечатка пальца является невидимый Unicode управляющий символ «слева направо» . Попробуйте выбрать начальную кавычку и первый символ отпечатка большого пальца, удалив их (что также избавит от невидимого промежуточного символа), и заново введите их вручную.


Я сам сегодня подвергся такому странному поведению, и мне потребовалось больше часа, чтобы понять это. Наконец-то я понял это с помощью отладчика для проверки длин и хеш-кодов findValue и Thumbprint объекта сертификата, который оказался разным. Это заставило меня проверить массивы символов тех строк в отладчике, где обнаружился невидимый символ.

45 голосов
/ 07 июля 2014

Я взял некоторые ответы здесь и объединил их в статический метод, который заботится об удалении специальных символов и всего верхнего регистра. Надеюсь, кто-то еще может использовать его.

    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();
        }
    }
22 голосов
/ 20 марта 2014

У меня была такая же проблема, и я решил ее:

  1. Я скопировал отпечаток пальца из mmc напрямую в VS. Я сравнил строки и не нашел никакой разницы.

  2. Проверка длины с помощью hash.length, была разница, 41 против 40.

В строку добавлен невидимый символ Char, скопировавший его из mmc.


Решение:

  1. скопировать отпечаток пальца из mmc в Notepad.exe
  2. скопируйте эту строку снова
  3. вставить в свой код

Это работает.

8 голосов
/ 24 мая 2016

Это меня тоже смутило, я написал эту функцию для очистки отпечатка при копировании и вставке из 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];
8 голосов
/ 12 декабря 2013

Я стал жертвой этого.Мало того, что Unicode имел символ «слева направо» в оснастке консоли Windows для отображения отпечатка большого пальца, он также имел строчные шестнадцатеричные символы с пробелами между каждыми двумя символами.Выходные данные CertUtil также имели строчные буквы и пробелы.Чтобы получить совпадение, мне нужно было указать findValue в виде строки, которая была преобразована в

  1. Удалить главный специальный символ,
  2. Удалить пробел между кластерами символов,
  3. Изменить все символы на заглавные буквы .
2 голосов
/ 02 ноября 2012

Этот код должен работать.

Полагаю, вы скопировали этот отпечаток из консоли управления сертификатами.И это скопированное значение содержит нечитаемый символ Юникода, который невидим в Visual Studio.Попробуйте удалить первый невидимый символ, и если это то, о чем я думаю, это должно сработать.

1 голос
/ 15 января 2014

Я столкнулся с тем же.Я не мог найти этот ответ где-нибудь здесь, поэтому я опубликую его.Мне кажется, что функция поиска в магазине 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];
            }
        }
1 голос
/ 09 декабря 2011

Замените код, чтобы найти свой сертификат в магазине, как показано ниже:

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

Также 3-й параметр, который является сертификатом возврата bool, только если сертификат действителен.Поэтому убедитесь, что ваш сертификат действителен.Если у вас есть самозаверяющий сертификат или около того, просто передайте 3-й параметр как «false»

0 голосов
/ 14 сентября 2017

Просто чтобы вы знали, что такое невидимый символ, я вижу отпечаток большого пальца в mmc: 75 3a ...

Затем я копирую и вставляю его в свой vim, вижу следующее:

<200e> 75 3a ...

Так что после того, как вы избавитесь от первого символа "<200e>" и лишних пробелов, все будет в порядке.

0 голосов
/ 19 июня 2017

Я также сталкиваюсь с этим невидимым символом Unicode. Попытка использовать Блокнот (Windows 10) так или иначе не работала для меня. Наконец, я использую PowerShell, чтобы получить чистый гекс отпечатка большого пальца:

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

Так много для символа Юникод.

...