[c#] X509Store 인증서 관련 문제. 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();
    }
}



답변

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


나는 오늘이 이상한 행동을 당했고 그것을 알아내는 데 한 시간 넘게 걸렸다. 나는 마침내 그것을보고하는 방법은의 길이와 해시 코드를 확인하기 위해 디버거를 사용하여이었다 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();
        }
    }


답변

나는 같은 문제가 있었고 그것을 해결했습니다.

  1. mmc에서 VS로 직접 지문을 복사했습니다. 문자열을 비교했지만 차이점이 발견되지 않았습니다.

  2. hash.length로 길이를 확인하면 41 대 40의 차이가 있습니다.

mmc에서 복사하여 문자열에 추가 된 보이지 않는 Char가 있습니다.


해결 :

  1. mmc에서 Notepad.exe로 지문 복사
  2. 이 문자열을 다시 복사
  3. 코드에 붙여 넣기

작동합니다.


답변

이로 인해 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];


답변

나는 이것에 희생되었습니다. 지문의 Windows 콘솔 스냅인 디스플레이에 유니 코드 “왼쪽에서 오른쪽으로”문자가있을뿐만 아니라 두 문자 사이에 공백이있는 소문자 16 진수 문자도있었습니다. CertUtil의 출력에도 소문자와 공백이 있습니다. 일치를 얻으려면 findValue를 다음으로 변환 된 문자열로 지정해야했습니다.

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


답변

이 코드는 작동합니다.

인증서 관리 콘솔에서이 지문을 복사했다고 가정합니다. 그리고 복사 된 값에는 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];
            }
        }