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 인증서 정보 대화 상자의 지문을 코드 (또는 간단한 예제 인 경우 구성 파일)에 복사하여 붙여 넣었다고 가정합니다. 짜증스럽게도 손도장 텍스트 상자의 첫 번째 문자는 보이지 않는 유니 코드 "왼쪽에서 오른쪽으로 표시"제어 문자 입니다. 여는 문자열 따옴표와 손도장의 첫 번째 문자를 선택하고 삭제 한 다음 (사이에 보이지 않는 문자도 제거됨) 손으로 다시 입력 해보십시오.


나는 오늘이 이상한 행동을 당했고 그것을 알아내는 데 한 시간 넘게 걸렸다. 나는 마침내 그것을보고하는 방법은의 길이와 해시 코드를 확인하기 위해 디버거를 사용하여이었다 findValue과의 Thumbprint서로 다른 것으로 밝혀졌다 인증서 객체의를. 이로 인해 보이지 않는 문자가 표시된 디버거에서 해당 문자열의 문자 배열을 검사했습니다.


4
다시 입력하는 것보다 더 쉬운 방법은 인증서 관리 콘솔 대화 상자에서 지문을 복사하여 텍스트 편집기 (예 : Notepad ++)에 붙여 넣는 것입니다. 그러면 보이지 않는 유니 코드 문자가 "?"로 나타납니다. 또는 다른 명백하게 이상한 캐릭터. 그런 다음 해당 문자를 nix하고 '업데이트 된'문자열을 코드 / 구성 / 텍스트 상자에 복사 할 수 있습니다.
nateirvin

2
@nateirvin : 맞습니다 (손으로 다시 입력하라는 제 제안은 약간 과잉이며 그 시점에서 제가 얼마나 좌절했는지 영감을 받았습니다)-또는 UTF-8 모드로 붙여넣고 숨겨진 문자 표시를 켭니다 (더 흥미 롭습니다). 정확히 어떤 캐릭터인지 보여주기 때문입니다.)
Aasmund Eldhuset 2013 년

1
@James (내가 쓴대로) 주변 따옴표도 삭제하면 삭제 될 것이라고 생각하지만 실제로 전체 줄을 삭제하면 확실히 제거해야합니다.
Aasmund Eldhuset

1
여기에 문서화 된 버그 support.microsoft.com/en-us/kb/2023835 레슨은 MMC에서 복사 및 붙여 넣기를하지 않는 것입니다
Darryl Braaten

3
기록을 위해 지문은 대소 문자를 구분하지 않습니다. 단지 눈에 보이지 않는 문자를 삭제하려면 삭제를 칠도 VS2015와 메모장 내가 할 수 있었다 - 커서 키를 사용하여 첫 번째 장소에서 그것을 확인할 수 있었다
Simon_Weaver

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

6
Regex.Replace는 "[^ \ da-fA-F]"여야합니다. 지문은 16 진수 문자열입니다.
Ross Patterson

감사합니다, 그 Regex는 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 콘솔 스냅인 디스플레이에 유니 코드 "왼쪽에서 오른쪽으로"문자가있을뿐만 아니라 두 문자 사이에 공백이있는 소문자 16 진수 문자도있었습니다. CertUtil의 출력에도 소문자와 공백이 있습니다. 일치를 얻으려면 findValue를 다음으로 변환 된 문자열로 지정해야했습니다.

  1. 선행 특수 문자를 제거하고
  2. 문자 클러스터 사이의 공백을 제거하고,
  3. 모든 문자를 대문자로 변경하십시오 .

3

이 코드는 작동합니다.

인증서 관리 콘솔에서이 지문을 복사했다고 가정합니다. 그리고 복사 된 값에는 Visual Studio에서 볼 수없는 유니 코드 읽을 수없는 기호가 포함되어 있습니다. 첫 번째 보이지 않는 기호를 삭제하고 이것이 내가 생각하는 것이라면 이것이 작동합니다.


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

또한 bool 인 세 번째 매개 변수는 인증서가 유효한 경우에만 인증서를 반환합니다. 따라서 인증서가 유효한지 확인하십시오. 자체 서명 된 인증서가있는 경우 세 번째 매개 변수를 "false"로 전달하십시오.


하드 코딩 된 메서드가 1 개의 값을 반환 할 때 인증서가 유효합니다. var results = store.Certificates.Find (findType, "7a6fa503ab57b81d6318a51ca265e739a51ce660", true); //result.Count = 1 :)
nunofamel 2011

런타임에 메서드에 전달되는 지문 ID가 무엇인지 확인할 수 있습니까?
Rajesh 2011

내가 Imediate 창에 두는 것이 정확하고 그는 같은 값을 가지고 있습니다 :(
nunofamel

코드에서 위와 같이 구문을 변경 했습니까?
Rajesh

이제 영어로 :) 내 응용 프로그램의 원래 코드는 위와 같습니다. 복사 + 붙여 넣기 오류
였습니다.)

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

이 보이지 않는 유니 코드 문자도 발생합니다. 메모장 (Windows 10)을 사용해도 나에게도 잘 작동하지 않았습니다. 마지막으로 PowerShell을 사용하여 깨끗한 지문 16 진수를 얻습니다.

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

유니 코드 문자에 너무 많이.


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

두 번째 매개 변수가 "findValue"라는 뜻이라고 생각합니다.


두 번째 매개 변수는 실제로 findValue입니다.
nunofamel 2011

그렇다면 문제는 다른 곳에 있습니다. 리터럴 문자열 대 문자열 변수 매개 변수는 실제 내용이 다르지 않는 한 이와 같이 중단되지 않습니다 (공백? 후행 줄 바꿈?)
Joe

0

보이지 않는 문자가 무엇인지 알려 드리기 위해 mmc의 지문이 75 3a ...

그런 다음 Vim에 복사하여 붙여 넣으면 다음이 표시됩니다.

<200e> 75 3a ...

따라서 첫 번째 문자 "<200e>"와 추가 공백을 제거하면 괜찮습니다.


0

Aasmund Eldhuset의 답변 (및 기타 답변)에 +1.

귀찮게도 지문 텍스트 상자의 첫 번째 문자는 보이지 않는 유니 코드 "왼쪽에서 오른쪽으로 표시"제어 문자입니다.

그것이 존재하는지 확인하는 것은 어려울 수 있습니다. 예를 들어, 내 구성 파일에서 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. 메모장에서 Visual Studio로 지문을 복사합니다.
  3. Visual Studio를 관리자로 실행합니다.

이것은 매력처럼 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.