Использование клиентских сертификатов для Windows RT (Windows 8.1/Windows Phone 8.1)

Я пытаюсь использовать новую функцию Windows 8.1 и Windows Phone 8.1, а именно хранилища сертификатов и возможность использовать клиентские сертификаты для аутентификации клиентов на стороне сервера. Однако у меня возникают проблемы с этой функциональностью.

У меня есть базовая тестируемая служба WCF, которая работает на IIS express. IIS express настроен на поддержку SSL и клиентских сертификатов. В файле конфигурации IIS (configurationhost.config) я установил это:

<access sslFlags="SslRequireCert" /> (tried also SslNegotiateCert)
<clientCertificateMappingAuthentication enabled="true" />

Я добавил сертификат клиента в приложение Windows RT, как показано ниже:

//Install the self signed client cert to the user certificate store
string CACertificate = null;
try
{
    Uri uri = new Uri("ms-appx:///Assets/AdventureWorksTestClient1.pfx");
    var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    using (DataReader dataReader = DataReader.FromBuffer(buffer))
    {
       byte[] bytes = new byte[buffer.Length];
       dataReader.ReadBytes(bytes);
       // convert to Base64 for using with ImportPfx
       CACertificate = System.Convert.ToBase64String(bytes);
    }
    await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
            CACertificate,
            "",
            ExportOption.Exportable,
            KeyProtectionLevel.NoConsent,
            InstallOptions.None,
            "ClientCert1");
 }
 catch (Exception ex)
 {...

Затем я использую HttpBaseProtocolFilter, к которому я добавляю сертификат клиента следующим образом:

IReadOnlyCollection<Certificate> certs = await CertificateStores.FindAllAsync(query);

HttpBaseProtocolFilter bpf = new HttpBaseProtocolFilter();
if (certs.Count > 0)
{
    cert = certs.ElementAt(0);
    bpf.ClientCertificate = cert;
}
HttpClient httpClient = new HttpClient(bpf);
....

И затем запросите:

var resp = await httpClient.GetAsync(new Uri(serviceURL));

Эта строка кода генерирует это исключение:

{System.Exception: Exception from HRESULT: 0x80072F7D
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at JumpStartCertificateDemo.MainPage.<btnCallService_Click>d__0.MoveNext()}

Я на 100% уверен, что импортировал правильные сертификаты также на localhost (локальный компьютер), а также на стороне приложения. Вызов службы через браузер работает правильно. (Мне предлагается предоставить клиентский сертификат), поэтому должна быть какая-то проблема с предоставлением сертификата клиента в приложении.

Может ли кто-нибудь помочь мне в этом, пожалуйста? Спасибо.

Ответ 1

Проблема может быть связана с действительностью сертификата, который вы используете.

По умолчанию .Net отказывается устанавливать соединение https с недействительным или не доверенным сертификатом.

Обычно сертификат недействителен, поскольку он генерируется не доверенным органом (самоподписанным сертификатом) или потому, что адрес сайта не включен в список допустимых адресов для сертификата.

В .Net это ограничение может быть ослаблено, см. это обсуждение С# Игнорировать ошибки сертификата?