it-roy-ru.com

Проблемы с сертификатами X509Store. Найти 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 возвращает 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();
    }
}
70
nunofamel

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

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

118
Aasmund Eldhuset

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

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

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

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

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

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


Решение:

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

Работает.

22
Thomas

Это тоже сбило меня с толку, я написал эту функцию для очистки отпечатка при копировании и вставке из 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
Rob C

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

  1. Удалить ведущий специальный символ,
  2. Удалить пробелы между кластерами символов,
  3. Измените все символы на прописные буквы .
8
Greg

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

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

2
Dmitry Dyachkov

Я столкнулся с этим же. Я не мог найти этот ответ где-нибудь здесь, поэтому я опубликую его. Мне кажется, функция поиска 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
vikingben

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

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

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

1
Rajesh

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

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

<200e> 75 3a ...

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

0
iefgnoix

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

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

Так много для Unicode Char.

0
Riza Marhaban

Вот простая версия кода для вышеупомянутых предложений, конечно, которая работает для меня

 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;
    }
0
Jay
var results = store.Certificates.Find(findType, findType, true);

Я думаю, что вы имеете в виду второй параметр, который будет "findValue". 

0
Joe