Устранение сбоя установления связи с предупреждением sslv3 при попытке использовать сертификат клиента

Я пытаюсь подключиться к сервису, которому для авторизации требуется сертификат. Процесс заключается в том, что я отправляю сервису CSR-файл. Сервис подписывает CSR и отправляет мне сертификат, который я использую для подключения.

  1. Я сгенерировал CSR с помощью следующей командной строки:

    openssl req -new -nodes -newkey rsa:2048 -keyout cert.key -out cert.csr
    
  2. Я взял содержимое cert.csr и отправил им. Они генерируют сертификат клиента, и я получил обратно файл PEM.

  3. Теперь я пытаюсь подключиться, используя их файл сертификата в SSLCERT для curl () и предоставляя закрытый ключ из cert.key как CURLOPT_SSLKEY - (который я получил на шаге 1).

  4. Не удается: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

Что я делаю не так в этом процессе?

Это работает, когда я пытаюсь использовать полученный тестовый сертификат, включающий закрытый ключ от службы (самоподписанный сертификат). Но когда я использую сертификат, который они сгенерировали из моего CSR, а затем использую мой закрытый ключ в качестве ключа, возникает ошибка с ошибкой рукопожатия.

Итак, я знаю, что это не имеет отношения к тому, что openssl / curl не поддерживает v3 / TLS и т. Д., Что другие при поиске решения обнаружили, что их проблема была.

Вот что я бегу:

  curl -i -v --request POST https://service.com/ --cert clientcert.pem --key private_key.pem --cert-type pem --tlsv1.1 --insecure
* Connected to service.com (1xx.xxx.xxx.xx) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS alert, Server hello (2):
* error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
* Closing connection 0

Запуск следующих версий: curl 7.35.0 (x86_64-pc-linux-gnu) libcurl / 7.35.0 OpenSSL / 1.0.1f zlib / 1.2.8 libidn / 1.28 librtmp / 2.3


person Karem    schedule 02.04.2016    source источник
comment
Никакой закрытый ключ никуда не отправляется, не говоря уже о SSL. Вот почему они называются частными. Трудно понять, о чем вы здесь спрашиваете.   -  person user207421    schedule 02.04.2016
comment
@EJP Хорошо, но мне нужно отправить закрытый ключ, потому что единственное, что я получаю от них, - это сертификат (сгенерированный из созданного мной CSR)? Я что-то упускаю?   -  person Karem    schedule 02.04.2016
comment
@EJP Я должен отправить закрытый ключ, иначе ошибка не может установить файл закрытого ключа:   -  person Karem    schedule 02.04.2016
comment
Вам необходимо использовать свой закрытый ключ в конфигурации SSL вашей конечной точки. Вы не отправляете его никуда, никогда и никогда. И SSL тоже. Он просто использует его для подписи сообщения сертификата, отправленного одноранговому узлу.   -  person user207421    schedule 02.04.2016
comment
«Установить» не означает «отправить». Вам необходимо убедиться, что настраиваемый вами закрытый ключ соответствует подписанному CSR, который вы также используете в конфигурации.   -  person user207421    schedule 02.04.2016
comment
@EJP Я имел в виду установить, а не отправлять, спасибо за указание. Когда я настраиваю CURL для использования полученного от них тестового сертификата + тестового закрытого ключа, он работает. Когда я настраиваю CURL для использования сертификата, созданного из моего CSR + мой закрытый ключ, он не работает. Итак, я неправильно генерирую подписанный CSR, поскольку полагаю, что моя ошибка не совпадает?   -  person Karem    schedule 02.04.2016
comment
Еще одно предположение: должен ли сертификат клиента из службы быть сгенерирован из того же CSR, который мы использовали для нашего сертификата на нашем веб-сайте https?   -  person Karem    schedule 02.04.2016
comment
curl -i -v ... - См. справочную страницу cURL и часть о Заставить [ing] curl использовать TLS версии 1.x при согласовании с удаленным TLS-сервером ....   -  person jww    schedule 02.04.2016
comment
curl ... --key private_key.pem... - Согласно команде OpenSSL, которую вы использовали для создания CSR, ваш ключ называется cert.key; а не private_key.pem.   -  person jww    schedule 02.04.2016
comment
@jww Я использую cert.key (я просто скопировал и переименовал его). Я использую --tlsv1.1, но также пробовал tlsv1.2 - тот же сбой рукопожатия.   -  person Karem    schedule 02.04.2016


Ответы (4)


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

Я предполагаю, что они предоставили вам сертификат, у которого либо неправильный эмитент (хотя их сервер мог использовать для этого более конкретный код предупреждения), либо неправильная тема. Мы знаем, что сертификат совпадает с вашим частным ключом, потому что оба curl и openssl client соединили их в пару, не жаловавшись на несоответствие; но мы на самом деле не знаем, что он соответствует их желаемому ЦС - потому что ваш curl использует openssl, а клиент openssl SSL НЕ обеспечивает соответствие настроенного сертификата клиента certreq.CAs.

Сделайте openssl x509 <clientcert.pem -noout -subject -issuer и то же самое с сертификатом из теста P12, который работает. Сделайте openssl s_client (или отметьте тот, который вы сделали) и посмотрите под Acceptable client certificate CA names; имя там или одно из них должно совпадать (точно!) с эмитентом (ами) ваших сертификатов. Если нет, то, скорее всего, это ваша проблема, и вам нужно проверить с ними, что вы отправили CSR в правильное место и правильным способом. Возможно, у них разные режимы в разных регионах или бизнес-направлениях, или тестирование vs prod, или active vs pending и т. Д.

Если эмитент вашего сертификата совпадает с желаемым CA, сравните его тему с рабочим (test-P12): они в аналогичном формате? есть ли какие-то компоненты в рабочем, которых нет в вашем? Если они позволяют это, попробуйте сгенерировать и отправить новый CSR с именем субъекта, точно таким же, как у test-P12, или как можно более близким, и посмотрите, даст ли это сертификат, который работает лучше. (Для этого вам не нужно создавать новый ключ, но если вы захотите, отслеживайте, какие сертификаты соответствуют каким ключам, чтобы вы не перепутали их.) Если это не так. Не помогите взглянуть на расширения сертификатов с openssl x509 <cert -noout -text на предмет каких-либо различий, которые могут быть связаны с авторизацией субъекта, например KeyUsage, ExtendedKeyUsage, может быть Policy, может быть Constraints, может быть, даже что-то нестандартное.

Если ничего не помогает, спросите операторов серверов, что их журналы говорят о проблеме, или, если у вас есть доступ, посмотрите журналы самостоятельно.

person dave_thompson_085    schedule 02.04.2016
comment
Спасибо за Ваш ответ. Я только что проверил. Эмитент и субъект имеют одинаковый формат как для p12 (тестовый сертификат, который работает), так и для действующего клиентского сертификата, который я пытаюсь использовать. Есть различия как в эмитенте, так и в теме, но это только данные, а не формат / структура. Что осталось от вашего ответа, так это попробовать openssl s_client и увидеть допустимый сертификат клиента. Попробую, смогу ли я подключиться и проверить это прямо сейчас. - person Karem; 03.04.2016
comment
Вот и все! Разные названия CA (test vs prod)! - person Karem; 03.04.2016
comment
@Karem, как вы решили проблему, вы имели в виду, что использовали ssl-сертификаты с другим доменом, например. sub.site.com или bus.site.com? - person Nono; 09.11.2020

Какой закрытый ключ SSL нужно отправить вместе с сертификатом клиента?

Никто из них :)

Одна из привлекательных особенностей клиентских сертификатов заключается в том, что они не делают глупых вещей, таких как передача секрета (например, пароля) в виде простого текста на сервер (HTTP basic_auth). Пароль по-прежнему используется для разблокировки ключа для сертификата клиента, просто он не используется напрямую во время обмена или для аутентификации клиента.

Вместо этого клиент выбирает временный случайный ключ для этого сеанса. Затем клиент подписывает временный случайный ключ своим сертификатом и отправляет его на сервер (некоторая рука отказывается). Если злоумышленник что-то перехватит, это случайно, поэтому его нельзя будет использовать в будущем. Его нельзя даже использовать для второго запуска протокола с сервером, потому что сервер также выберет новое случайное значение.


Не удается: ошибка: 14094410: подпрограммы SSL: SSL3_READ_BYTES: сбой квитирования предупреждения sslv3

Используйте TLS 1.0 и выше; и используйте указание имени сервера.

Вы не предоставили никакого кода, поэтому мне не ясно, как сказать вам, что делать. Вместо этого вот командная строка OpenSSL, чтобы проверить это:

openssl s_client -connect www.example.com:443 -tls1 -servername www.example.com \
    -cert mycert.pem -key mykey.pem -CAfile <certificate-authority-for-service>.pem

Вы также можете использовать -CAfile, чтобы избежать «ошибки проверки: num = 20». См., Например, «Проверить ошибку: num = 20» при подключении к gateway.sandbox.push.apple.com.

person jww    schedule 02.04.2016
comment
Спасибо за объяснение. Я все еще в замешательстве. Для тестирования я получил .p12, который я извлек, чтобы получить как сертификат, так и файл закрытого ключа. Это отлично работает (!) При настройке в curl (с использованием openssl) в CURLOPT_SSLCERT + CURLOPT_SSLKEY. Теперь для реального клиентского сертификата, который генерируется (на их стороне) из CSR, который я сгенерировал на моем сервере, я не получаю от них закрытого ключа, а затем подумал, что хорошо, может быть, мне следует использовать закрытый ключ, который я получил при создании CSR и поместите его как CURLOPT_SSLKEY. Не сработало (что привело меня к этому вопросу). - person Karem; 02.04.2016
comment
А теперь вы и другие говорите, что закрытый ключ ставить вообще не надо. Если у меня нет набора закрытого ключа (с помощью CURLOPT_SSLKEY), я получаю сообщение об ошибке «Невозможно установить файл закрытого ключа»: (не удается найти закрытый ключ в сертификате клиента). Так много разочаровывающих часов, и я просто не могу этого понять. - person Karem; 02.04.2016
comment
Я использую TLS 1.2 (и, как уже говорилось, все работает с тестовым клиентским сертификатом + тестовым закрытым ключом). Я чувствую, что что-то упускаю / Я что-то очень неправильно понял. - person Karem; 02.04.2016
comment
@Karem - у вас есть закрытый ключ с момента создания CSR. Его нет в сертификате клиента, поскольку он имеет только открытый ключ. Согласно команде OpenSSL, которую вы показали: -keyout cert.key. Проверьте файловую систему на наличие cert.key. - person jww; 02.04.2016
comment
Точно! И это тот, который я использую. Сертификат. Я взял его содержимое и поместил в private_key.pem для запуска в команде curl (см. Обновленный вопрос) в параметре --key. Но я по-прежнему получаю сообщение об ошибке «Ошибка рукопожатия». - person Karem; 02.04.2016
comment
OpenSSL 1.0.1 и выше автоматически согласовывает SSL3 через TLS1.2; SSL3_READ_BYTES в сообщении об ошибке является общим именем подпрограммы и НЕ означает, что SSL3 используется. -tls1 фактически ограничивает вас только 1.0; если вам нужна какая-либо опция, она должна быть -no_ssl3, что позволяет использовать от 1.0 до 1.2. curl автоматически выполняет SNI, хотя openssl s_client требуется -servername (плюс теперь мы видим, что предупреждение находится на втором этапе после правильного выбора и сертификата сервера). - person dave_thompson_085; 03.04.2016
comment
@ dave_thompson_085 Отличный вклад, спасибо. Я просто также попробовал -no_ssl3, но это не имело никакого значения, кроме записи [данные не показаны] для каждого результата вывода. То же сообщение об ошибке. - person Karem; 03.04.2016

Решением для меня в системе CentOS 8 была проверка политики системной криптографии путем проверки того, что / etc / crypto-policy / config читает значение по умолчанию DEFAULT, а не любое другое ценность.

После изменения этого значения на ПО УМОЛЧАНИЮ выполните следующую команду:

/usr/bin/update-crypto-policies --set DEFAULT

Повторно запустите команду curl, и она должна работать.

person canon    schedule 24.09.2020

В моем случае причиной ошибки было то, что я импортировал только сертификат (например, cert1.pem) и закрытый ключ (например, privkey1.pem) в хранилище ключей, и для решения проблемы мне также пришлось импортировать полную цепочку сертификатов.
Я получил следующие файлы от центра сертификации Let's Encrypt:

privkey1.pem
fullchain1.pem
chain1.pem
cert1.pem

Итак, я сделал следующее:

  1. Объедините содержимое трех файлов сертификатов в файл с именем all.pem:
cat cert1.pem chain1.pem fullchain1.pem > all.pem
  1. Создайте мое хранилище ключей, содержащее полную цепочку сертификатов:
openssl pkcs12 -export -in all.pem -inkey privkey1.pem -out my_keystore.p12 -name mycertalias -CAfile chain1.pem -caname root
person Víctor Gil    schedule 19.04.2021