2014-09-25 4 views
1

Я разрабатываю очень простое приложение для рабочего стола (win forms), которое взаимодействует с сервером через службу WCF по протоколу HTTPS. Каждый клиент, использующий это приложение, может загрузить клиентский сертификат (уникальный для каждого клиента), который должен использоваться для связи.C# WCF связь с сертификатом клиента

Что именно я пытаюсь достичь: 1. Пользователь будет «загрузить» сертификат на моем рабочем столе приложения, приложения взять сертификат и программно сохранить сертификат на окна CERT магазина, вот мой код:

[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. Теперь, когда я загрузил сертификат на окна магазина, я хочу, чтобы использовать его для ФОС общения, так что мой код выглядит следующим образом:

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

И, наконец, вот моя проблема, когда я пытаюсь вызвать некоторые метод на прокси, плохой получить исключение: System.ServiceModel.Security.SecurityNegotiationException: Не удалось установить защищенный канал для SSL/TLS с полномочиями «url (i changed this)». ---> 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, если пользователь, выполняющий этот процесс, имеет доступ для чтения к закрытому ключу. –

+0

Grzegorz похоже, что вы спасли мне жизнь. Похоже, это была моя проблема! :) Испытайте это и напишите, если это сработает! :) –

ответ

1

В конце концов, мне нужно это:

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

Теперь сертификат импортируется только правом и может быть использован для связи без каких-либо проблем

Смежные вопросы