2014-09-25 55 views
1

我正在開發非常簡單的桌面(win表單)應用程序,它通過HTTPS協議通過WCF服務與服務器通信。 每個使用此應用程序的客戶端都可以上傳客戶端證書(每個客戶端都是唯一的),用於通信。C#與客戶端證書的WCF通信

正是我努力實現: 1.用戶將「上傳」證書到我的桌面應用程序,應用程序需要的證書和程序保存證書,證書商店的櫥窗,這裏是我的代碼:

[SecurityCritical] 
public CertificateInfoDto GetCertificateInfoAndImportToStore(string fullPath, SecureString password) 
    { 
     if (string.IsNullOrEmpty(fullPath)) 
     { 
      throw new ArgumentNullException("fullPath"); 
     } 

     if (!File.Exists(fullPath)) 
     { 
      throw new ArgumentException(string.Concat("No file present on ", fullPath)); 
     } 

     try 
     { 
      byte[] rawBytes = this.GetCertificateContent(fullPath); 
      var certificate = new X509Certificate2(rawBytes, password, X509KeyStorageFlags.Exportable); 
      this.EnsureImport(certificate); 
     } 
    // some error handling etc, and end of method. 


[SecurityCritical] 
private void EnsureImport(X509Certificate2 certificate) 
{ 
    X509Store store = null; 
    try 
    { 
     store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
     store.Open(OpenFlags.ReadWrite); 
     store.Add(certificate); 
    } 

在我的應用程序設置文件中,我只存儲證書序列號。 2.現在,當我已經上傳證書Windows應用商店,我想使用它的WCF溝通,使我的代碼看起來像:

var client = new SomeWcfServiceProxy(); 
client.ClientCredentials.ClientCertificate.SetCertificate(
      StoreLocation.CurrentUser, 
      StoreName.My, 
      X509FindType.FindBySerialNumber, 
      certificateSerialNumber); 

最後,這裏是我的問題,當我嘗試調用一些方法代理,虐待得到一個異常: System.ServiceModel.Security.SecurityNegotiationException:無法建立安全通道的SSL/TLS與權威'網址(我改變了這一點)'。 ---> System.Net.WebException:請求被中止:無法創建SSL/TLS安全通道。

但什麼讓我困惑,就是當我創建代理客戶是這樣的:

var client = new SomeWcfServiceProxy(); 
var clientCertificate = new X509Certificate2(@"C:\U\BB\certificate.pfx", "password"); 
client.ClientCredentials.ClientCertificate.Certificate = clientCertificate; 

一切工作就像一個魅力! 所以我的問題是:我不想在任何地方存儲客戶端證書密碼,我想要通過Windows證書存儲上傳它,然後僅從Windows證書存儲區使用它。這可能嗎?或者我必須在某處存儲證書密碼(我不知道在哪裏,因爲我認爲它不是很安全,而且這個證書是非常非常保密的)。 感謝您的幫助:)

+1

也許你的用戶沒有權限到證書的私鑰。 檢查mmc控制檯是否運行該進程的用戶有權讀取私鑰。 – 2014-09-25 12:34:30

+0

Grzegorz它看起來像你拯救了我的生命。看起來這正是我的問題! :)我會測試它,並寫入它是否會工作! :) – 2014-09-25 13:00:00

回答

1

畢竟,我需要這樣的:

var certificate = new X509Certificate2(rawBytes, password, X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 

現在證書導入恰到好處,可以用於通信,沒有任何問題