Ошибка вызова 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 для службы, с которой общаюсь, в свои доверенные корневые центры сертификации и в личные хранилища.
  • В коде приложения я вытаскиваю сертификат по миниатюре. Я вижу в отладчике, что присутствуют как закрытые, так и открытые ключи.
  • Я инициализирую TcpClient
  • Затем я инициализирую SslStream, используя TcpClient
  • Я вызываю AuthenticateAsClient()
  • Я получаю сообщение об ошибке

Для параметра имени хоста AuthenticateAsClient() я также пытался использовать CN корня ЦС, а также 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, поэтому не знаю, почему он не передается.


person Sinaesthetic    schedule 16.02.2016    source источник


Ответы (1)


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

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