Я разрабатываю очень простое приложение для рабочего стола (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. Это возможно? Или я должен где-то хранить пароль сертификата (я не знаю, где, потому что я считаю, что он не очень безопасен, и эти сертификаты очень конфиденциальны). Спасибо за любую помощь :)
Может быть, ваш пользователь не имеет права доступа к закрытому ключу сертификата. Проверьте консоль mmc, если пользователь, выполняющий этот процесс, имеет доступ для чтения к закрытому ключу. –
Grzegorz похоже, что вы спасли мне жизнь. Похоже, это была моя проблема! :) Испытайте это и напишите, если это сработает! :) –