Sự cố với chứng chỉ X509Store. Tìm kiếm FindByThumbprint


84

Tôi đang gặp sự cố khi sử dụng phương pháp này 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();
    }
}

Trong trường hợp này, Phương thức Tìm trả về 0 kết quả ( results.Count == 0), nhưng nếu tôi đặt findValue là hằng số thì phương thức tìm chứng chỉ.

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

Câu trả lời:


135

Tôi giả sử rằng bạn đã sao chép dấu ngón tay cái từ hộp thoại thông tin chứng chỉ Windows vào mã của bạn (hoặc vào tệp cấu hình nếu đây là một ví dụ đơn giản). Thật khó chịu, ký tự đầu tiên trong hộp văn bản dấu vân tay là ký tự điều khiển Unicode "trái sang phải" ẩn . Hãy thử chọn trích dẫn chuỗi mở đầu và ký tự đầu tiên của dấu vân tay, xóa chúng (cũng sẽ loại bỏ ký tự ẩn ở giữa) và nhập lại chúng bằng tay.


Bản thân tôi hôm nay đã phải chịu hành vi kỳ quặc này, và tôi đã mất hơn một giờ để tìm ra nó. Cách cuối cùng tôi thấy nó là sử dụng trình gỡ lỗi để kiểm tra độ dài và mã băm của findValuevà của Thumbprintđối tượng chứng chỉ, hóa ra là khác nhau. Điều này khiến tôi phải kiểm tra các mảng ký tự của các chuỗi đó trong trình gỡ lỗi, nơi ký tự ẩn hiện xuất hiện.


4
Một cách dễ dàng hơn so với việc nhập lại là sao chép dấu vân tay từ hộp thoại bảng điều khiển quản lý chứng chỉ và dán nó vào trình soạn thảo văn bản (như Notepad ++), tại thời điểm đó, ký tự Unicode ẩn sẽ xuất hiện dưới dạng dấu "?" hoặc một số nhân vật rõ ràng là kỳ quặc khác. Sau đó, bạn có thể loại bỏ ký tự đó và sao chép chuỗi 'cập nhật' vào mã / cấu hình / hộp văn bản của bạn.
nateirvin

2
@nateirvin: Đúng (gợi ý của tôi là nhập lại bằng tay hơi quá mức cần thiết và được truyền cảm hứng bởi tôi đã thất vọng như thế nào vào thời điểm đó) - hoặc dán nó ở chế độ UTF-8 và bật hiển thị các ký tự ẩn (điều này thậm chí còn thú vị hơn bởi vì nó cho bạn biết chính xác đó là ký tự).
Aasmund Eldhuset

1
@James Tôi tin rằng nó sẽ bị xóa nếu bạn cũng xóa các dấu ngoặc kép xung quanh (như tôi đã viết), nhưng thực sự, xóa toàn bộ dòng chắc chắn sẽ loại bỏ nó.
Aasmund Eldhuset

1
Bug tài liệu ở đây support.microsoft.com/en-us/kb/2023835 bài học là không sao chép và dán từ MMC
Darryl Braaten

3
đối với bản ghi, dấu vân tay không phân biệt chữ hoa chữ thường. cũng trong VS2015 và notepad tôi đã có thể chỉ cần nhấn delete để xóa các nhân vật vô hình - và xác minh nó có ở nơi đầu tiên với các phím con trỏ
Simon_Weaver

49

Tôi đã lấy một số câu trả lời ở đây và kết hợp chúng thành một phương thức tĩnh giúp loại bỏ mọi ký tự đặc biệt và chữ hoa. Hy vọng rằng ai đó khác có thể sử dụng nó.

    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
Đây nên được chấp nhận là câu trả lời. Hoạt động hoàn hảo !!
Aster Veigas

6
Regex.Replace đó phải là "[^ \ da-fA-F]" - dấu vân tay là chuỗi thập lục phân.
Ross Patterson

Cảm ơn, Regex vừa giải quyết được vấn đề tôi gặp phải sau khi chửi thề trong nửa giờ.
Frans

Đẹp regex để thỏa thuận với điều đó gây phiền nhiễu bí mật-ẩn-nhân vật voodoo ...
granadaCoder

23

Tôi đã gặp vấn đề tương tự và đã giải quyết nó:

  1. Tôi đã sao chép trực tiếp Vân tay từ mmc sang VS. Tôi đã so sánh các chuỗi và không tìm thấy bất kỳ sự khác biệt nào.

  2. Kiểm tra độ dài với hash.length, có sự khác biệt, 41 so với 40.

Có một Char vô hình được thêm vào chuỗi bằng cách sao chép nó ra khỏi mmc.


Giải quyết:

  1. sao chép Vân tay từ mmc sang Notepad.exe
  2. sao chép lại chuỗi này
  3. dán vào mã của bạn

Nó đang hoạt động.


10

Điều này cũng khiến tôi vấp phải, tôi đã viết hàm này để làm sạch dấu vân tay khi sao chép và dán từ 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

Tôi đã trở thành nạn nhân của điều này. Không chỉ có ký tự Unicode "từ trái sang phải" trong hiển thị dấu tay của bảng điều khiển Windows mà nó còn có các ký tự hex viết thường, với khoảng cách giữa hai ký tự. Đầu ra của CertUtil cũng có các ký tự viết thường và khoảng trắng. Để có được một kết quả phù hợp, tôi phải chỉ định findValue là một chuỗi đã được chuyển đổi thành

  1. Xóa ký tự đặc biệt hàng đầu,
  2. Xóa khoảng trắng giữa các cụm ký tự,
  3. Thay đổi tất cả các ký tự thành chữ hoa .

3

Mã này sẽ hoạt động.

Tôi cho rằng bạn đã sao chép dấu vân tay này từ bảng điều khiển quản lý chứng chỉ. Và giá trị được sao chép đó chứa biểu tượng không đọc được unicode mà nó không thể nhìn thấy được trong Visual Studio. Cố gắng xóa biểu tượng vô hình đầu tiên và nếu đây là những gì tôi nghĩ đến, điều này sẽ hoạt động.


2

Tôi đã gặp phải điều tương tự. Tôi không thể tìm thấy câu trả lời này ở bất kỳ đâu trong đây nên tôi sẽ đăng nó. Có vẻ như đối với tôi, chức năng tìm X509Store không hoạt động. Tôi đã xác minh điều này bằng một vòng lặp for đơn giản và truy xuất chứng chỉ theo cách thủ công.

  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

Thay thế mã để tìm chứng chỉ của bạn trong cửa hàng như bên dưới:

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

Ngoài ra, tham số thứ 3 là chứng chỉ trả về bool chỉ khi chứng chỉ hợp lệ. Vì vậy, hãy đảm bảo rằng chứng chỉ của bạn là hợp lệ. Nếu bạn có chứng chỉ tự ký hoặc tương tự thì chỉ cần vượt qua tham số thứ 3 là "false"


Chứng chỉ hợp lệ, vì khi đặt mã cứng phương thức trả về 1 giá trị var results = store.Certificates.Find (findType, "7a6fa503ab57b81d6318a51ca265e739a51ce660", true); //result.Count = 1 :)
nunofamel

Bạn có thể kiểm tra Id dấu vân tay đang được chuyển vào thời gian chạy cho phương thức nào không?
Rajesh

là đúng tôi đặt chúng trên cửa sổ Imediate, và ông có giá trị như nhau :(
nunofamel

Bạn có thay đổi cú pháp thành cú pháp như được hiển thị ở trên trong mã của bạn không?
Rajesh

Bây giờ bằng tiếng Anh :) Các mã gốc trong ứng dụng của tôi cũng giống như ở trên, nó chỉ là một bản sao + dán lỗi :)
nunofamel

1

Đây là phiên bản mã đơn giản cho các đề xuất ở trên- dĩ nhiên là nó phù hợp với tôi

 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

Tôi cũng gặp phải ký tự Unicode vô hình này. Việc thử sử dụng Notepad (Windows 10) bằng cách nào đó cũng không hoạt động tốt với tôi. Cuối cùng, tôi sử dụng PowerShell để có được hex dấu vân tay rõ ràng:

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

Quá nhiều cho ký tự Unicode.


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

Tôi nghĩ ý bạn là tham số thứ 2 là "findValue".


param thứ 2 thực sự là findValue,
nunofamel

Nếu đúng như vậy, thì vấn đề nằm ở chỗ khác. Một chuỗi chữ so với một tham số biến chuỗi sẽ không bị phá vỡ như thế này trừ khi nội dung thực tế khác (khoảng trắng? Dấu dòng mới?)
Joe

0

Để cho bạn biết ký tự ẩn là gì, tôi thấy dấu vân tay trong mmc là: 75 3a ...

Sau đó, tôi sao chép và dán nó vào vim của mình, tôi thấy như sau:

<200e> 75 3a ...

Vì vậy, sau khi bạn loại bỏ ký tự đầu tiên "<200e>" và các khoảng trắng thừa, bạn sẽ ổn.


0

+1 cho câu trả lời của Aasmund Eldhuset (và các câu trả lời khác).

Thật khó chịu, ký tự đầu tiên trong hộp văn bản dấu vân tay là ký tự điều khiển Unicode "trái sang phải" ẩn.

Thật khó để xác minh rằng nó có mặt. Ví dụ: sao chép dấu ngón tay cái từ tệp cấu hình của tôi sang trình chỉnh sửa nhị phân VS đôi khi nhận được ký tự ẩn và đôi khi không.

Ngoài ra mã này không thể hiển thị một vấn đề. Tôi đã xem qua mã và di chuyển qua x509Store để tìm chứng chỉ mà tôi muốn.

                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

Sau khi phân tích dài, đây là những gì đã làm việc cho tôi.

  1. Sao chép bản in ngón tay cái từ chứng chỉ vào sổ tay.
  2. Sao chép bản in ngón tay cái từ notepad sang studio trực quan.
  3. Chạy visual studio với tư cách quản trị viên.

Công việc này như một cái duyên vậy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.