Сбой рукопожатия SSL с ошибкой рукопожатия предупреждения sslv3: номер предупреждения SSL 40

У меня есть файл .pfx, который может прекрасно подключаться к удаленному серверу при использовании на клиенте Windows. Теперь я хочу подключиться к серверу с помощью клиента Linux.

Проблема 1) Я использовал следующие команды openssl для извлечения открытого сертификата и закрытого ключа из файла pfx,

openssl pkcs12 -in Name.pfx -nocerts -out priv.pem -nodes
openssl pkcs12 -in Name.pfx -nokeys -out pub.pem

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

openssl rsa -noout -text -in priv.pem | openssl md5
openssl x509 -noout -text -in pub.pem | openssl md5

Проблема 2) Вместо этого я использовал следующую команду для извлечения одного файла pem из pfx, который имеет как сертификат, так и ключ.

openssl pkcs12 -in Name.pfx -out bundle.pem

Используя этот файл pem, я попытался подключиться к удаленному серверу с помощью следующей команды:

openssl s_client -servername 1.2.3.4 -connect 1.2.3.4:1234 -CAfile bundle.pem -state -tls1_2

Это дает следующий вывод на терминале

CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=0 O = "My Name", CN = Name - Local
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:handshake failure
SSL_connect:failed in SSLv3 read finished A
140250807310240:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1275:SSL alert number 40
140250807310240:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
---
Certificate chain
 0 s:/O=My Name /CN=Name - Local
   i:/O=My Name /CN=Name - Local
---
Server certificate
-----BEGIN CERTIFICATE-----
<random string of certificate>
-----END CERTIFICATE-----
subject=/O=My Name /CN=Name - Local
issuer=/O=My Name /CN=Name - Local
---
No client certificate CA names sent
Server Temp Key: ECDH, secp521r1, 521 bits
---
SSL handshake has read 1332 bytes and written 206 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: <some string>
    Session-ID-ctx: 
    Master-Key: <some string>
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1495217834
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

Я не могу понять, почему рукопожатие не работает. Застрял на 3 дня, где именно проблема.


person Abhay Jain    schedule 19.05.2017    source источник


Ответы (1)


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

openssl rsa -noout -text -in priv.pem | openssl md5
openssl x509 -noout -text -in pub.pem | openssl md5

Первая команда показывает текстовую информацию о закрытом ключе. Вторая текстовая информация о сертификате, который содержит открытый ключ. Конечно, эти данные разные.

Используя этот файл pem, я попытался подключиться к удаленному серверу с помощью следующей команды:

openssl s_client -servername 1.2.3.4 -connect 1.2.3.4:1234 -CAfile bundle.pem -state -tls1_2

При этом сертификат используется как доверенный ЦС (-CAfile). Это, вероятно, не то, что вы хотите. Вместо этого вы хотите использовать сертификат в качестве сертификата клиента. Это должно быть сделано как описано с помощью параметров -cert и -key, т.е. -cert bundle.pem -key bundle.pem в вашем случае.

Кроме того, -servername должно быть именем хоста, а не IP-адресом. Если у вас нет имени хоста, пропустите этот параметр.

SSL_connect:SSLv3 read server certificate request A
...
SSL_connect:SSLv3 write client certificate A
...
SSL3 alert read:fatal:handshake failure

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

person Steffen Ullrich    schedule 19.05.2017
comment
Но есть статьи (например, kb.wisc.edu/middleware/page.php? id=4064 ), которые говорят, что вывод md5 этих двух файлов должен быть одинаковым. Кроме того, я удалил флаг CAfile и вместо этого использовал флаги сертификата и ключа, как вы предложили. Терминал запрашивает парольную фразу, а затем снова выходит из строя, говоря об ошибке установки закрытого ключа 140495240427424: ошибка: 0B080074: процедуры сертификата x509: X509_check_private_key: несоответствие значений ключей: x509_cmp.c: 331: - person Abhay Jain; 19.05.2017
comment
@AbhayJain: вы используете опцию -text. В статье, на которую вы ссылаетесь, вместо нее используется опция -modulus. С последним вариантом результат должен быть таким же, с первым вариантом нет. - person Steffen Ullrich; 19.05.2017
comment
@AbhayJain: а что касается другой вашей проблемы, см. stackoverflow.com/questions/4658484/ - person Steffen Ullrich; 19.05.2017
comment
Я заменил -text на -modulus, но они все равно не совпадают. Я использую неправильную команду для извлечения из pfx? - person Abhay Jain; 20.05.2017
comment
@AbhayJain: я предполагаю, что ваш файл pfx содержит несколько сертификатов, то есть листовой сертификат и сертификаты цепочки. В этом случае openssl x509 возьмет первый экспортированный сертификат, который может быть неверным (то есть сертификат цепочки) и, следовательно, не соответствовать ключу. И из-за этого неправильного порядка вы также получаете более поздние проблемы, как описано в вопросе, на который я ссылался. Попробуйте использовать -clcerts только для экспорта листового сертификата. - person Steffen Ullrich; 20.05.2017
comment
У меня была такая же проблема, и добавление сертификата клиента решило ее. Но не понимаю, почему это необходимо предоставить, это должно быть необязательно, не так ли? - person Badr; 23.04.2019
comment
@Badr: Это полностью зависит от сервера, если он а) запрашивает сертификат клиента в первую очередь и б) соглашается с тем, что клиент не отправляет его, даже если он запрошен. Если серверу требуется сертификат клиента, его предоставление необязательно. - person Steffen Ullrich; 23.04.2019