メソッド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証明書情報ダイアログボックスのthumb印をコード(または簡単な例の場合は構成ファイル)にコピーアンドペーストしたと仮定します。迷惑なことに、thumb印テキストボックスの最初の文字は 目に見えないUnicodeの「左から右のマーク」制御文字 です。文字列の最初の引用符とprint印の最初の文字を選択して削除し(その間に見えない文字も削除されます)、手動で再入力してみてください。
今日私はこの奇妙な行動を自分で受け、それを理解するのに1時間以上かかりました。私が最終的に見たのは、デバッガーを使用して、証明書オブジェクトの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からコピーして貼り付けたときにthumb印をきれいにするためにこの関数を書きました。
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];
私はこれの犠牲になりました。 console印のWindowsコンソールスナップイン表示にUnicodeの「左から右」文字があっただけでなく、2文字ごとにスペースがある小文字の16進文字もありました。 CertUtilの出力には、小文字とスペースも含まれていました。一致を取得するには、findValueを変換された文字列として指定する必要がありました
このコードは動作するはずです。
証明書管理コンソールからこのthumb印をコピーしたと思います。そして、そのコピーされた値には、Visual Studioでは見えないUnicodeの読み取り不可能なシンボルが含まれています。最初の不可視のシンボルを削除してみてください。これが私の考えだとしたら、これは動作するはずです。
私はこれと同じことに遭遇しました。ここにこの答えが見つからなかったので、投稿します。私にとっては、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);
また、boolである3番目のパラメーターは、証明書が有効な場合にのみ証明書を返します。そのため、証明書が有効であることを確認してください。自己署名証明書などがある場合は、3番目のパラメーターを渡して「false」にします
目に見えないキャラクターが何であるかを知らせるために、MMCのthumb印が75 3a ...
次に、それをコピーしてvimに貼り付けます。次のように表示されます。
<200e> 75 3a ...
したがって、最初の文字「<200e>」と余分なスペースを削除したら、問題ありません。
この目に見えないUnicode文字にも遭遇します。何らかの理由でメモ帳(Windows 10)を使用してみてもうまくいきませんでした。最後に、PowerShellを使用して、きれいなthumb印の16進数を取得します。
PS C:\> $tp= (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "mycert"}).Thumbprint;
PS C:\> $tp
Unicode文字についてはこれだけです。
ここに上記の提案のためのコードの簡単なバージョンがあります-もちろん私のために働いています
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;
}
var results = store.Certificates.Find(findType, findType, true);
2番目のパラメーターが「findValue」であることを意味すると思います。