2010-12-01 89 views
4

想象一下,我們使用WCF(私鑰/公鑰對)使用經典的不對稱簽名。顯然這是安全的,直到私鑰不被盜。我們不需要鑰匙之間的任何信任鏈,對吧?客戶端只需要知道其服務器的公鑰,反之亦然。可以使用WCF的自簽名證書安全嗎?

只有當客戶端事先不知道服務器的公鑰並在第一次訪問時獲得它時,纔會出現問題。這裏我們有一個風險,即實際的服務器是一個「中間人」而不是真正的服務器。我們需要證書。客戶端訪問服務器,獲取其證書(其中包含公鑰),並且驗證它。

驗證客戶端需要確保服務器的證書是針對此特定服務器頒發的。在這裏,我們需要信任鏈。對?

如果客戶端通過WCF使用MessageSecurity.Mode = Certificate預先知道服務器的證書(它的公鑰),那麼即使證書是自簽名的,我們可以說通信是安全的嗎?

Usualy認爲使用自簽名certifacate不安全,應始終避免在生產中使用。
但是爲什麼?如果客戶端知道預期的公鑰,然後獲得證書,將其視爲可信(通過將其公鑰與預期的公鑰相匹配),那麼它不會取消服務器必須使用其私鑰加密有效載荷這一事實。當且僅當私鑰和公鑰一起創建時,密鑰才能用pulbic密鑰成功解密。

你能在我的推理中看到任何缺陷嗎?

如果它是正確的,那麼我可以確定使用自定義X509CertifacateValidator並將客戶端代理的ClientCredentials.ServiceCertificate.DefaultCertificate設置爲某些固定(在客戶端上)X509Certificate安全嗎?

定製X509CertifacateValidator是這樣的:

public class CustomCertificateValidator : X509CertificateValidator 
{ 
    private readonly X509Certificate2 m_expectedCertificate; 

    public CustomCertificateValidatorBase(X509Certificate2 expectedCertificate) 
    { 
     m_expectedCertificate = expectedCertificate; 
    } 

    public override void Validate(X509Certificate2 certificate) 
    { 
     ArgumentValidator.EnsureArgumentNotNull(certificate, "certificate"); 

     if (certificate.Thumbprint != m_expectedCertificate.Thumbprint) 
      throw new SecurityTokenValidationException("Certificated was not issued by trusted issuer"); 
    } 
} 
+0

我認爲這與信任有關,而不是安全。證書頒發機構(CA)頒發的證書是可信的,例如,如果FF或IE瀏覽器將顯示綠色欄,如果他們信任簽名證書的CA。 (Geotrust或Verisign) 生成您自己的證書並保證您的私鑰安全,應該沒問題,但是256位VeriSign證書可以比自己生成的256位證書更安全嗎? CA可以做的一件有用的事是撤消證書。在這種情況下,客戶端可以檢查CA,以確保證書仍然有效。 – 2010-12-01 17:58:36

回答

6

是的,你的理解是正確的,但是它忽略了一兩件事 - 東西隨着時間的推移而改變。如果服務器的私鑰被泄露或者服務器的證書以其他方式(無論何種方式)變得無效,PKI提供證書撤銷和撤銷檢查的機制。並且使用自簽名證書這是不可能的(至少不建立定製的PKI基礎設施)。

解決此問題的一種方法是創建將用作CA證書的自定義自簽名證書。使用此證書籤署服務器證書並將吊銷信息放入CA證書。然後在客戶端添加CA證書作爲可信,並對該CA證書執行服務器證書驗證並檢查撤銷。這意味着您必須在某些(可能是私有的)Web服務器上發佈CRL,或者運行OCSP響應程序。

+0

+1 - 我在想同樣的事情,但並非100%確定。另外我認爲一些生成證書的算法比其他算法更好?同樣增加密鑰大小可能會使某些證書更加安全。我的意思是,花更長的時間來猜測關鍵。 – 2010-12-01 18:04:22