2014-12-05 31 views
5

Tôi có các ứng dụng máy khách/khách hàng tùy chỉnh giao tiếp với nhau bằng kết nối TCP được mã hóa SSL (giao thức tùy chỉnh). Để thiết lập chứng chỉ máy chủ, tôi đã tạo một tổ chức phát hành chứng chỉ tự ký và sử dụng nó để ký chứng chỉ cho máy chủ để sử dụng. Về phía khách hàng, tôi muốn xác minh rằng chứng chỉ của máy chủ mà tôi đang kết nối được ký bởi CA tự ký của tôi.xác minh chứng chỉ máy chủ đối với tổ chức phát hành chứng chỉ tự ký

Tôi đã có thể làm việc này trong C++ bằng cách tăng ngữ cảnh ssl :: chứng chỉ CA tự ký bằng cách sử dụng hàm load_verify_file(). Tôi muốn thực hiện các chức năng tương tự trong một máy khách C#, nhưng các công cụ .NET SSL có vẻ nghiêm ngặt hơn nhiều trong việc tin tưởng các chứng chỉ không có trong kho lưu trữ tin cậy Windows.

Tôi đã tìm thấy một số giải pháp từng phần trong tìm kiếm của tôi cho đến nay. Rõ ràng là X509Chain is the class to use to verify SSL certificates. Tôi đã thử mã số like this nhưng chuỗi được tạo theo cách thủ công vẫn than phiền rằng chứng chỉ gốc không đáng tin cậy, giống như chuỗi gốc được chuyển vào hàm xác minh. Có một tùy chọn để ignore unknown certificate authorities, nhưng điều đó có nghĩa là nó sẽ chấp nhận bất kỳ chứng chỉ tự ký nào, chắc chắn không phải là những gì tôi muốn.

Đây là mã dường như gần nhất với những gì tôi muốn, nhưng như đã nêu ở trên, tôi có vấn đề là nó vẫn phàn nàn về chứng chỉ tôi thêm vào ExtraStore đang được tự ký. Có cách nào để thuyết phục X509Chain tin tưởng vào chứng chỉ mà tôi đang cung cấp không?

bool remoteCertificateValidationCallback(
    object sender, X509Certificate certificate, X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    // make sure certificate was signed by our CA cert 
    X509Chain verify = new X509Chain(); 
    verify.ChainPolicy.ExtraStore.Add(secureClient.CertificateAuthority); // add CA cert for verification 
    //verify.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; // this accepts too many certificates 
    verify.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking 
    verify.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; 
    if (verify.Build(new X509Certificate2(certificate))) 
    { 
     return true; // success? 
    } 
    return false; 
} 

Trả lời

5

Tôi nghi ngờ chứng chỉ CA cá nhân của bạn chưa được cài đặt trên hệ thống hiện tại (nơi bạn chạy mã) hoặc cài đặt không chính xác. Chứng chỉ CA gốc phải được cài đặt trong kho chứa Trusted Root CAs của khung máy tính, không phải trong cửa hàng người dùng hiện tại. Theo mặc định, X509Chain sử dụng cửa hàng máy tính để tra cứu các neo đáng tin cậy.

Ngoài ra, mã của bạn không thực hiện những gì bạn muốn. Nó sẽ chấp nhận và chuyển cho bất kỳ CA gốc đáng tin cậy nào. Thay vào đó, bạn cần phải so sánh phần tử cuối cùng trong X509Chain.ChainElements, cho dù chứng chỉ được chứa là chứng chỉ bạn đang mong đợi (bằng cách so sánh các giá trị vân tay). Bạn nên áp dụng sửa chữa lừa đảo:

if (verify.Build(new X509Certificate2(certificate))) 
{ 
    return verify.ChainElements[verify.ChainElements.Count - 1] 
     .Certificate.Thumbprint == cacert.thumbprint; // success? 
} 
return false; 

nơi cacert là chứng chỉ CA gốc của bạn.

+1

bạn là chính xác, tôi không cài đặt chứng chỉ CA vào cửa hàng đáng tin cậy. Tôi đã hy vọng tránh phải làm điều đó. Nhưng có vẻ như tôi không thể làm những gì tôi muốn với các công cụ tích hợp sẵn mà .NET có. Tôi chỉ nhận thấy [câu hỏi này] (http://stackoverflow.com/questions/7695438/verify-remote-server-x509certificate-using-ca-certificate-file) trong Related có vẻ gần giống nhau (chúng không chỉ định nếu CA họ đang sử dụng là tự ký). Nó không có câu trả lời hay. – plasmoidia

+1

'X509Chain.Build' gọi nội bộ' CertCreateCertificateChainEngine' chức năng dựa trên một cửa hàng chứng chỉ địa phương để thiết lập một sự tin tưởng. Bạn có thể tránh yêu cầu này bằng cách loại bỏ câu lệnh IF bên ngoài và không sử dụng kết quả phương thức. Nó là đủ cho câu hỏi chính xác của bạn. – Crypt32

+0

Vì vậy, so sánh các thuộc tính Dấu vân tay của hai chứng chỉ sẽ kiểm tra xem chúng có giống nhau hay không? Điều đó có thể làm việc và thậm chí tôi có thể sử dụng biến 'chain' được truyền vào (có chuỗi thích hợp từ máy chủ). Tôi chỉ có thể kiểm tra rằng 'chain.ChainStatus' chỉ chứa' UntrustedRoot' để đảm bảo rằng chuỗi cũng hợp lệ và không chỉ có CA kết thúc vào cuối? – plasmoidia

Các vấn đề liên quan