"Ошибка вызова SSPI" при подключении к серверу OpenSSL

При звонке AuthenticateAsClient(), Я получаю сообщение об ошибке "Ошибка вызова SSPI". с внутренним исключением "Полученное сообщение было неожиданным или неправильно отформатированным".

Я видел, что это полупопулярная проблема, но я не смог найти работающего решения. Вот где я нахожусь после прочтения статей в течение нескольких часов:

  • Используя мой закрытый ключ, сервер выдал мне подписанный сертификат клиента
  • Используя open ssl, я объединил их в pfx, используя:

    openssl pkcs12 -in My-Client-Cert.pem -inkey ssl-client-privatekey.pem -export -out private-key-pair.pfx

  • Я импортировал сертификат в личную папку на LocalMachine. Я был в состоянии видеть, что свидетель признал, что закрытый ключ присутствовал.
  • Закрытый ключ не защищен паролем
  • Я импортировал CA Root для службы, с которой я разговариваю, как в свои Trusted Root Certification Authorities, так и в личные магазины.
  • В коде приложения я извлекаю сертификат по эскизу. В отладчике я вижу, что присутствуют как закрытые, так и открытые ключи.
  • Я инициализирую TcpClient
  • Затем я инициализирую SslStream, используя TcpClient
  • Я вызываю AuthenticateAsClient()
  • Я получаю сообщение об ошибке

Для параметра имени хоста AuthenticateAsClient() Я также попытался использовать CN корня CA и CN сертификата клиента с тем же результатом.

Я проверил, что сервис, с которым я пытаюсь общаться, работает нормально, когда я подключаюсь к нему с помощью openssl s_client connect

Вот код для подключения:

private void Setup(string hostname, int port, X509Certificate2Collection certs)
{
    try
    {
        // create the socket
        var clientSocket = new TcpClient(hostname, port);
        _sslStream = new SslStream(
            clientSocket.GetStream(),
            false,
            ValidateServerCertificate,
            null);

        _sslStream.AuthenticateAsClient(
            "VirtuCrypt Root CA - Test", // hostname here must match the name on the server certificate
            certs,
            SslProtocols.Tls11,
            false);

        Debug.WriteLine("Connected!");
    }
    catch(Exception ex)
    {
        Debug.WriteLine(ex.Message);

        if(ex.InnerException != null)
            Debug.WriteLine(ex.InnerException.Message);
    }
}

Выдернуть мои волосы... есть мысли?

ОБНОВЛЕНИЕ: я ускорил Wireshark и заметил, что вся связь с хостом и с него осуществлялась по TCP, и ни одна из них не была выполнена по TLS. Не уверен, что это то, что меня должно беспокоить, несмотря на то, что я запрашиваю TLS12

ОБНОВЛЕНИЕ 2: Я снова смотрю на Wireshark и исправил декодирование, чтобы оно показывало связь TLS в дополнение к соединению TCP. Теперь, когда я вижу рукопожатие, я вижу, что сертификат клиента фактически не представлен. Я предоставляю этот сертификат SslStream, поэтому я не знаю, почему он не передается.

1 ответ

Решение

Хорошо, после того, как я наконец подружился с Wireshark и разбил около 4 кофейных кружек, преследующих мой хвост, вот что я узнал...

  • Корень CA, который нам дали, был файлом pem, который на самом деле включал корень CA и 3 промежуточных сертификата.
  • Мне пришлось разбить их на отдельные файлы и импортировать корень CA в наше хранилище доверенных корневых CA и 3 промежуточных сертификата в промежуточное хранилище CA
  • Я не замечал раньше, но наш клиентский сертификат, который был установлен в личном магазине, говорил, что у него недостаточно информации для проверки, но на самом деле происходит сбой проверки, потому что у нас не было Сертификаты CA установлены правильно, как описано выше. Как только я установил их отдельно, это сообщение исчезло
  • Похоже, что.Net не отправит сертификат вашего клиента, если он не может быть проверен. Во втором редактировании OP я упомянул, что вижу, что сертификат клиента вообще не отправляется. Это была актуальная проблема. После того, как я установил эти сертификаты CA, сертификат начал получать, и все остальное было хорошо.
Другие вопросы по тегам