X509Store証明書の問題。FindByThumbprintを検索


84

メソッドを使用すると問題が発生します 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();
    }
}

回答:


135

拇印をWindows証明書情報ダイアログボックスからコード(または、これが単純化された例の場合は構成ファイル)にコピーして貼り付けたと思います。厄介なことに、拇印テキストボックスの最初の文字は、非表示のUnicode「左から右へのマーク」制御文字です。開始文字列の引用符と拇印の最初の文字を選択し、それらを削除して(これにより、間にある非表示の文字も削除されます)、手動で再入力してみてください。


今日、私はこの奇妙な行動にさらされました、そしてそれを理解するのに1時間以上かかりました。私が最終的に見たのは、デバッガーを使用して証明書オブジェクトの長さとハッシュコードをチェックすることfindValueでしたThumbprintが、これは異なることが判明しました。これにより、デバッガーでこれらの文字列の文字配列を調べ、非表示の文字が表示されました。


4
再入力するよりも簡単な方法は、証明書管理コンソールダイアログから拇印をコピーしてテキストエディター(Notepad ++など)に貼り付けることです。この時点で、非表示のUnicode文字は「?」として表示されます。または他の明らかに奇妙なキャラクター。次に、その文字をnixして、「更新された」文字列をコード/構成/テキストボックスにコピーできます。
nateirvin 2013年

2
@nateirvin:本当(手で再入力するという私の提案は少しやり過ぎで、その時点で私がどれほどイライラしていたかに触発されました)-またはUTF-8モードで貼り付けて、非表示の文字の表示をオンにします(これはさらに興味深いですそれがどの文字であるかを正確に示しているからです)。
Aasmund Eldhuset 2013年

1
@James(私が書いたように)周囲の引用符も削除すると削除されると思いますが、実際、行全体を削除すると間違いなく削除されるはずです。
Aasmund Eldhuset 2014

1
ここに記載されているバグsupport.microsoft.com/en-us/kb/2023835 レッスンはMMCからコピーアンドペーストしない
Darryl Braaten 2015

3
記録のために、拇印は大文字と小文字を区別しません。また、VS2015とメモ帳では、削除を押して非表示の文字を削除することができました。カーソルキーを使用して最初にそこにあることを確認しました
Simon_Weaver 2016年

49

私はここでいくつかの答えを取り、それらを組み合わせて、特殊文字と大文字のすべてを削除する静的メソッドを作成しました。うまくいけば、他の誰かがそれを使用することができます。

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

2
これは答えとして受け入れられるべきです。完璧に動作します!!
Aster Veigas 2016年

6
そのRegex.Replaceは "[^ \ da-fA-F]"である必要があります-拇印は16進文字列です。
ロスパターソン

おかげで、その正規表現は、30分間コードを宣誓した後の問題を解決しました。
Frans 2017年

その迷惑な秘密隠された字ブードゥー教...に対処するためのニース正規表現
granadaCoder

23

私は同じ問題を抱えていて、それを解決しました:

  1. 指紋をmmcからVSに直接コピーしました。文字列を比較しましたが、違いは見つかりませんでした。

  2. hash.lengthで長さを確認すると、41と40の違いがありました。

mmcからコピーして文字列に追加された非表示のCharがあります。


解決:

  1. 指紋をmmcからNotepad.exeにコピーします
  2. この文字列をもう一度コピーします
  3. コードに貼り付けます

動作しています。


10

これも私をつまずかせました。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];

9

私はこれの犠牲になりました。拇印のWindowsコンソールスナップインディスプレイにUnicodeの「左から右」の文字があっただけでなく、2文字ごとにスペースを入れた小文字の16進文字も含まれていました。CertUtilの出力にも、小文字とスペースが含まれていました。一致させるには、findValueをに変換された文字列として指定する必要がありました。

  1. 主要な特殊文字を削除し、
  2. 文字クラスター間の空白を削除し、
  3. すべての文字を大文字に変更します

3

このコードは機能するはずです。

この拇印を証明書管理コンソールからコピーしたと思います。そして、そのコピーされた値には、VisualStudioでは表示されないUnicodeの読み取り不可能な記号が含まれています。最初の非表示のシンボルを削除してみてください。これが私の考えである場合、これは機能するはずです。


2

私はこれと同じことに遭遇しました。この答えはここのどこにも見つからなかったので、投稿します。私には、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

以下のように、コードを置き換えてストアで証明書を見つけます。

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

また、ブール値である3番目のパラメーターは、証明書が有効な場合にのみ証明書を返します。したがって、証明書が有効であることを確認してください。自己署名証明書などをお持ちの場合は、3番目のパラメータを「false」に渡すだけです。


プットがハードコードされたメソッドが1つの値を返す場合、証明書は有効ですvar results = store.Certificates.Find(findType、 "7a6fa503ab57b81d6318a51ca265e739a51ce660"、true); //result.Count = 1 :)
nunofamel 2011

実行時にメソッドに渡される拇印IDを確認できますか?
ラジェッシュ2011

正しいです私はそれらをイミディエイトウィンドウに置きました、そして彼は同じ値を持っています:(
nunofamel 2011

コードで上記のような構文に変更しましたか?
ラジェッシュ2011

現在英語で:)私のアプリケーションの元のコードは上記のようなもので、コピーと貼り付けのエラー
でした

1

これが上記の提案のコードの簡単なバージョンです-もちろん私のために働いています

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

1

この目に見えないUnicode文字にも遭遇します。メモ帳(Windows 10)を使ってみても、どういうわけかうまくいきませんでした。最後に、PowerShellを使用して、きれいな拇印の16進数を取得します。

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

Unicode文字についてはこれだけです。


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

2番目のパラメータが「findValue」であることを意味していると思います。


2番目のパラメータは実際にはfindValueです
nunofamel 2011

その場合、問題は他の場所にあります。リテラル文字列と文字列変数パラメータは、実際のコンテンツが異なる場合を除いて、このように壊れることはありません(空白?末尾の改行?)
Joe

0

見えない文字が何であるかを知らせるために、mmcの拇印は次のようになっています:75 3a .. ..

次に、それをコピーしてvimに貼り付けます。次のように表示されます。

<200e> 75 3a..。

したがって、最初の文字「<200e>」と余分なスペースを取り除いた後は、問題ありません。


0

Aasmund Eldhusetの回答(およびその他の回答)は+1。

迷惑なことに、拇印テキストボックスの最初の文字は、非表示の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);

0

長い分析の後、これが私のために働いたものです。

  1. 拇印を証明書からメモ帳にコピーします。
  2. サムプリントをメモ帳からVisualStudioにコピーします。
  3. 管理者としてVisualStudioを実行します。

これは魅力のように機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.