Двусторонний обмен SSL-сертификатами на виртуальной машине Azure - PullRequest
0 голосов
/ 31 октября 2019

У нас есть веб-приложение, которое должно взаимодействовать со службой HTTP, используя двустороннюю аутентификацию SSL-сертификата. Ниже приведен соответствующий код

        X509Certificate certificate = GetCertFromStore(StoreName.My, StoreLocation.LocalMachine, certName);
        if (certificate != null)
        {
            Log.Debug($"Adding client cert {certificate.Subject}");

            WebRequestHandler handler = new WebRequestHandler();

            handler.ClientCertificates.Add(certificate);
            handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.UseProxy = false;

            using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var postObj = new
                {
                    // somestuff
                };
                var postBody = JsonConvert.SerializeObject(postObj);

                var httpContent = new StringContent(postBody, Encoding.UTF8, "application/json");

                HttpResponseMessage httpResponse = client.PostAsync(queryUrl, httpContent).Result;
                if (httpResponse.IsSuccessStatusCode)
                {
                    // codey code
                }
                else
                {
                    Log.Error($"some error stuff.");
                }
            }
        }
        else
        {
            Log.Error($"Unable to find the certificate with name: {certName}");
        }

. В настоящее время мы используем самозаверяющий сертификат, который мы предоставили стороннему поставщику услуг и установили соответствующий сертификат сервера из них.

На локальной машине разработки все работает хорошо - соединение установлено, и вызовы службы и ответы проходят правильно.

Однако, когда мы развернули на виртуальной машине Azure (нашей тестовой среде),Обмен сертификатами не удается. Глядя на трассировку Wireshark, мы видим, что сертификат сервера принят, но он показывает, что отправлено 0 клиентских сертификатов. Мы знаем, что сертификат клиента находится в хранилище (из-за ведения журнала), и из трассировки Wireshark видно, что имя сертификата клиента действительно указано в «Отличительных именах» запроса сертификата сервера.

Не могу понять, как, хотя код добавляет наш ожидаемый сертификат клиента в WebRequestHandler, он исчезает во время рукопожатия.

1 Ответ

0 голосов
/ 04 ноября 2019

У нас все получилось.

Сначала я думаю, что сертификат был установлен без его закрытого ключа. В нашей функции GetCertFromStore он находил сертификат, но я думаю, потому что у него не было закрытого ключа, он не отправлял его. (Тот факт, что он находил сертификат, нас смущал - мы предполагали, что если он его найдет, все будет хорошо.)

Чтобы исправить это, мы удалили его из хранилища, а затем переустановили, используя. pfx-файл, обязательно импортируя закрытый ключ.

Возникла дополнительная проблема с разрешениями, ответ на которую мы нашли в StackOverflow здесь (обратите внимание, ответ не помечен как«ответ», но ответ о разрешениях). Чтобы веб-приложение могло загружать и использовать сертификат с закрытым ключом, удостоверение пула приложений (или олицетворенный пользователь) должно иметь разрешения на чтение для файла ключа установленного сертификата (обычно находится в C: \ ProgramData \ Microsoft \ Crypto \ RSA\ MachineKeys).

...