2014-12-05 43 views
5

SSL şifreli bir TCP bağlantısı (birbiri arasında iletişim kuralı) kullanarak birbiriyle iletişim kuran özel sunucu/istemci uygulamaları var. Sunucu sertifikasını ayarlamak için, kendinden imzalı bir sertifika yetkilisi oluşturdum ve sunucunun kullanacağı bir sertifikayı imzalamak için kullandım. İstemci tarafında, bağlandığım sunucunun sertifikasının kendim imzalı CA'm tarafından imzalandığını doğrulamak istiyorum.Sunucu sertifikasını kendinden imzalı sertifika yetkilisine karşı doğrulayın

Ssl :: context'in load_verify_file() işlevini kullanarak kendinden imzalı CA sertifikası vererek, C++ ile bu çalışmayı destekleyebilirim. Aynı işlevselliği bir C# istemcisinde uygulamak istiyorum, ancak .NET SSL malzeme, Windows güven deposunda olmayan sertifikalara güvenmek için çok daha sıkı görünüyor.

Şu ana kadar aramamda birkaç kısmi çözüm buldum. Görünüşe göre X509Chain is the class to use to verify SSL certificates. like this kodunu denedim, ancak el ile oluşturulan zincir, kök sertifikanın güvenilmez olduğunu ve tıpkı doğrulama işlevine aktarılan orijinal zincir gibi, hala şikayet ediyor. ignore unknown certificate authorities için bir seçenek var, ama bu kesinlikle istediğim değil herhangi bir kendinden imzalı sertifika kabul edecek gibi görünüyor.

Bu, istediğime en yakın görünen koddur, ancak yukarıda belirtildiği gibi, kendim imzalı Ekstra Deposu'na eklediğim sertifika hakkında hala şikâyet etmem sorunum var. X509Chain'i verdiğim sertifikaya güvenmeye ikna etmenin bir yolu var mı?

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

cevap

5

olursa, özel CA sertifikası (eğer kod çalıştırmasına olduğu) mevcut sistemde yüklü değil veya yanlış yüklü olduğunu sanıyorum. Kök CA sertifikası, geçerli kullanıcı deposunda değil, Computer stire'ın Güvenilen Kök CA'lar kapsayıcısında yüklü olmalıdır. Varsayılan olarak, X509Chain güvenilir ankrajları aramak için bilgisayar mağazasını kullanır.

Ayrıca, kodunuz ne istediğinizi gerçekleştirmiyor. Yaygın olarak güvenilen herhangi bir kök CA'yı kabul edip iletir. Bunun yerine, X509Chain.ChainElements'daki son öğeyi, içerilen sertifikanın beklediğiniz değer olup olmadığını (parmak izi değerlerini karşılaştırarak) karşılaştırmanız gerekir. foolowing düzeltme uygulamalıdır:

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

cacert kök CA sertifikası olduğunu.

+1

Haklısınız, CA sertifikasını güvenilir mağazaya yüklemiyorum. Bunu yapmaktan kaçınmayı umuyordum. Ancak, .NET'in sahip olduğu yerleşik araçlarla istediğimi yapamayacağım daha muhtemel görünüyor. Sadece (bu soru) (http://stackoverflow.com/questions/7695438/verify-remote-server-x509certificate-using-ca-certificate-file) İlişkili'de neredeyse aynı gibi gözüktüğünü fark ettim. Kullandıkları CA'nın kendi kendine imzalanmış olup olmadığını belirtin). İyi bir cevabı yok. – plasmoidia

+1

'X509Chain.Build, bir sertifika oluşturmak için yerel bir sertifika deposuna dayanan CertCreateCertificateChainEngine' işlevini dahili olarak çağırır. Bu gereksinimi dış IF deyimini kaldırarak ve yöntem sonucunu kullanmadan önleyebilirsiniz. Tam sorunuz için yeterli. – Crypt32

+0

Yani iki sertifikanın Thumbprint özelliklerini karşılaştırmak, aynı olup olmadığını kontrol edecek? Bu işe yarayabilir ve hatta geçecek olan 'zincir' değişkenini (sunucudan uygun zincire sahip olan) bile kullanabilirim. Zincirin aynı zamanda geçerli olmasını ve sadece CA'nın bitmesine izin vermediğinden emin olmak için 'chain.ChainStatus'' un sadece 'UntrustedRoot' içerdiğini kontrol edebilir miyim? – plasmoidia

İlgili konular