Проблемы с сертификатами 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();
}
}
Ответы
Ответ 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 > " и дополнительных пробелов, все будет в порядке.