openssl 1.0.2j, как заставить сервер выбирать ECDH * шифры - PullRequest
0 голосов
/ 24 октября 2018

У меня есть клиентский сервер, который использует opensl 1.0.2j и использует ключ и сертификат RSA: 4096, и хочу заставить сервер использовать только следующие шифры.

ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-SHA384
ECDH-RSA-AES128-GCM-SHA256
ECDH-RSA-AES128-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-SHA256
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256

Мой код на стороне сервера будет выглядетькак показано ниже.

method = SSLv23_server_method();
ctx = SSL_CTX_new(method);
SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256");
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tmp_dh(ctx, dh);
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
SSL_CTX_use_certificate_file(ctx, certFilePath, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, privKeyPath, SSL_FILETYPE_PEM)
SSL_accept()

Мой код на стороне клиента будет выглядеть следующим образом

method = SSLv23_server_method();
ctx = SSL_CTX_new(method);
SSL_CTX_set_cipher_list(ctx, "ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-SHA256");
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tmp_dh(ctx, dh);
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
SSL_CTX_use_certificate_file(ctx, certFilePath, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, privKeyPath, SSL_FILETYPE_PEM)
SSL_connect()

Последний шаг ssl_accept () на сервере завершается неудачно с

err: 336027900 'error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol'

Если я использую шифры ECDHE*RSA* или DHE*RSA* на стороне клиента, он работает нормально.

Не могли бы вы сообщить мне, что мне не хватает?

Редактировать: сертификат сервера (certFilePath) содержит открытый ключ RSA, а не открытый ключ ECDH.

1 Ответ

0 голосов
/ 25 октября 2018

Мета: ответ только до TLS1.2;1.3 больше не имеет функции обмена ключами и аутентификации в ciphersuite.

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

Во-вторых, «статические» шифры ECDH весьма отличаются от наборов ECDHE, так же как «статические» наборы DH отличаются от наборов DHE.Обе статические формы не получили широкого применения и очень мало используются, потому что они обычно не дают никакой выгоды;в частности, OpenSSL 1.1.0 и выше больше не реализуют их, поэтому ваш код устареет примерно через год, если я правильно запомнил расписание.

Если быть точным, то для наборов DH-RSA требуется сертификат, содержащий ключ DH (который разрешает keyAgreement), а для TLS <= 1.1 сертификат должен выдаваться <em>CA с использованием RSAключ;для 1.2 это последнее ограничение снято.Ни один публичный центр сертификации не выдаст сертификат для ключа DH, и даже сделать это самостоятельно непросто;см https://security.stackexchange.com/questions/44251/openssl-generate-different-type-of-self-signed-certificate и (мой) https://crypto.stackexchange.com/questions/19452/static-dh-static-ecdh-certificate-using-openssl/.

Для комплектов ECDH-RSA аналогичным образом требуется сертификат, содержащий ключ ECC, который разрешает keyAgreement, и выдается RSA, если <= 1.1;это несколько проще, потому что ключ (и CSR) для ECDH такой же, как и для ECDSA, и должен отличаться только KeyUsage.Для вашего самостоятельно созданного и самоподписанного случая это просто, просто сгенерируйте ключ ECC и сертификат (автоматически подписанный с помощью ECDSA).</p>

Но последнее, это не должно вызывать «неизвестный протокол»;это вызвало бы 'нет общего шифра' и handshake_failure.Код, который вы показали, не должен вызывать «неизвестный протокол», поэтому вам, вероятно, нужно сначала исследовать и исправить это.Вместо этого вы можете попробовать использовать командную строку s_client, особенно с ее хуками -debug или -msg, или -trace, если вы скомпилировали это.

...