X509存储证书的问题.查找查找指纹
本文关键字:查找 指纹 问题 存储 证书 X509 | 更新日期: 2023-09-27 18:17:34
使用方法时遇到问题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();
}
}
我想您已将 Windows 证书信息对话框中的指纹复制粘贴到您的代码中(如果这是一个简化的示例,则粘贴到配置文件中(。令人讨厌的是,指纹文本框中的第一个字符是不可见的 Unicode"从左到右标记"控件字符。尝试选择左字符串引号和指纹的第一个字符,删除它们(这也将去除中间的不可见字符(,然后手动重新键入它们。
我今天自己也遭受了这种奇怪的行为,我花了一个多小时才弄清楚。我最终看到它的方式是使用调试器检查findValue
的长度和哈希代码以及证书对象的Thumbprint
,结果证明是不同的。这导致我在调试器中检查这些字符串的字符数组,其中出现了不可见字符。
我在这里获取了一些答案,并将它们组合成一个静态方法,该方法负责删除特殊字符和大写字母。 希望其他人可以使用它。
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();
}
}
我遇到了同样的问题并解决了它:
-
我将指纹从mmc直接复制到VS。我比较了字符串,没有发现任何差异。
-
用hash.length检查长度,有区别,41和40。
通过将其从 mmc 中复制出来,将不可见的 Char 添加到字符串中。
解决:
- 将指纹从 mmc 复制到记事本.exe
- 再次复制此字符串
- 粘贴到代码
它正在工作。
我成了这个的受害者。 在 Windows 控制台管理单元显示的指纹中不仅有一个 Unicode"从左到右"字符,而且还具有小写十六进制字符,每两个字符之间有空格。 CertUtil 的输出也有小写字符和空格。 为了获得匹配,我必须将findValue指定为已转换为的字符串
- 删除前导特殊字符,
- 删除字符簇之间的空格,
- 将所有字符更改为大写。
这也让我绊倒了,我写了这个函数来清理从 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];
这段代码应该可以工作。
我想你已从证书管理控制台复制了此指纹。复制的值包含 Unicode 不可读符号,该符号在 Visual Studio 中是不可见的。尝试删除第一个不可见的符号,如果这就是我想到的,这应该有效。
我遇到了同样的事情。我在这里的任何地方都找不到这个答案,所以我会发布它。对我来说,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];
}
}
替换代码以在存储中查找证书,如下所示:
var results = store.Certificates.Find(findType, findValue, true);
此外,仅当证书有效时,布尔值的第三个参数才返回证书。因此,请确保您的证书有效。如果你有一个自签名证书,那么只需将第三个参数传递为"false">
这是上述建议的简单代码版本 - 当然对我有用
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;
}
我也遇到了这个不可见的 Unicode 字符。尝试使用记事本(Windows 10(对我来说也不好用。最后,我使用PowerShell来获得干净的指纹十六进制:
PS C:'> $tp= (Get-ChildItem -Path Cert:'LocalMachine'My | Where-Object {$_.Subject -match "mycert"}).Thumbprint;
PS C:'> $tp
对于 Unicode 字符来说太多了。
var results = store.Certificates.Find(findType, findType, true);
我想你的意思是第二个参数是"findValue"。
只是为了让你知道隐形字符是什么,我看到 mmc 中的指纹是:75 3a ...
然后我将其复制并粘贴到我的 vim 中,我看到以下内容:
<200e>75 3a ...
因此,在删除第一个字符"<200e>"和多余的空格后,您会没事的。
+1 表示 Aasmund Eldhuset 的答案(以及其他答案(。
令人讨厌的是,指纹文本框中的第一个字符是 不可见的 Unicode"从左到右标记"控制字符。
可能很难验证它是否存在。例如,将指纹从我的配置文件复制到 VS 二进制编辑器有时会获得不可见字符,有时不会。
此外,此代码未能显示问题。我逐步浏览代码并将鼠标悬停在 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);
经过长时间的分析,以下是对我有用的方法。
- 将指纹从证书复制到记事本。
- 将指纹从记事本复制到视觉工作室。
- 以管理员身份运行 Visual Studio。
这就像一个魅力。