Подтвердить что ты не робот

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

Ответ 1

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


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

Ответ 2

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

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

Ответ 3

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

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

  • Проверяя длину с hash.length, была разница, 41 против 40.

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


Решение:

  • скопируйте отпечаток от mmc к Notepad.exe
  • снова скопируйте эту строку
  • вставить в свой код

Работает.

Ответ 4

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

  • Удалите главный специальный символ,
  • Удалите пробелы между кластерами символов,
  • Измените все символы на заглавные.

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

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

Ответ 8

Я столкнулся с этим тем же. Я не мог найти этот ответ нигде здесь, поэтому я опубликую его. Мне кажется, что функция поиска X509Store просто не работает. Я проверил это простым циклом цикла и получал сертификат вручную.

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

Ответ 9

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

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

Ответ 10

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

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

Ответ 11

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

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

SO много для Unicode char.

Ответ 12

Чтобы сообщить вам, что такое невидимый персонаж, я вижу отпечаток в mmc: 75 3a...

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

< 200e > 75 3a...

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