Построить службу openssl с шифром ECDHE-RSA-AES128-GCM-SHA256

#c #mongoose #openssl

#c #мангуст #openssl

Вопрос:

Я создаю службу HTTPS с помощью Mongoose, используя OPENSSL (openssl-1.0.2) на встроенном Linux. Сначала я попробовал это, используя следующий список шифров «AES128-SHA256: AES256-SHA256: AES128-GCM-SHA256: AES256-GCM-SHA384», и он работает нормально. Однако, когда я пытаюсь использовать только «ECDHE-RSA-AES128-GCM-SHA256», компиляция все еще работает, но при попытке фактического HTTPS-соединения между сервером и клиентом (Chrome в Windows 10) соединение всегда прерывалось при рукопожатии.

Вот список поддерживаемых openssl шифров:

 # openssl ciphers | sed 's/:/n/g'
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
...
ECDH-RSA-AES256-GCM-SHA384
ECDH-ECDSA-AES256-GCM-SHA384
ECDH-RSA-AES256-SHA384
ECDH-ECDSA-AES256-SHA384
ECDH-RSA-AES256-SHA
ECDH-ECDSA-AES256-SHA
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-DES-CBC3-SHA
ECDHE-ECDSA-DES-CBC3-SHA
...

# 
  

Согласно перехвату пакетов между сервером и клиентом, клиент поддерживает ECDHE-RSA-AES128-GCM-SHA256, поэтому логически рукопожатие должно работать. Сертификат подписывается с использованием ключа RSA.

Вот мой код для настройки SSL-соединения.

 const char *pem = ctx->config[SSL_CERTIFICATE];
const char *chain = ctx->config[SSL_CHAIN_FILE];
if (!load_dll(ctx, SSL_LIB, ssl_sw) || !load_dll(ctx, CRYPTO_LIB, crypto_sw))
    return 0;
  
// Initialize SSL crap
SSL_library_init();
SSL_load_error_strings();

**if ((CTX = SSL_CTX_new(TLSv1_2_server_method())) == NULL)
    printf("SSL_CTX_new error: %s", ssl_error());**


/** Set cipher list */
//char cipher[128]="AES128-SHA256:AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384";
char cipher[128]="ECDHE-RSA-AES128-GCM-SHA256";
if (SSL_CTX_set_cipher_list(CTX, cipher) <= 0) {
    printf("Failed setting the cipher list.n");
    return 0;
}

if (CTX != NULL amp;amp; SSL_CTX_use_certificate_file(CTX, pem, SSL_FILETYPE_PEM) == 0) {
    printf("%s: cannot open %s: %s", __func__, pem, ssl_error());
    return 0;
}else if (CTX != NULL amp;amp; SSL_CTX_use_PrivateKey_file(CTX, pem, SSL_FILETYPE_PEM) == 0) {
    printf("%s: cannot open %s: %s", NULL, pem, ssl_error());
    return 0;
}

if (CTX != NULL amp;amp; chain != NULL amp;amp; SSL_CTX_use_certificate_chain_file(CTX, chain) == 0) {
    printf("%s: cannot open %s: %s", NULL, chain, ssl_error());
    return 0;
}
  

Все, что я сделал, это,

  1. Изменение метода с SSLv23_server_method() на TLSv1_2_server_method(),
  2. Изменение списка шифров с «AES128-SHA256: AES256-SHA256: AES128-GCM-SHA256: AES256-GCM-SHA384» на «ECDHE-RSA-AES128-GCM-SHA256»

Любая помощь была бы полезна, спасибо.

Комментарии:

1. Чтобы использовать наборы ECDHE в 1.0.x, вы должны вызвать либо (классический, но неуклюжий) SSL_[CTX_]set_tmp_ecdh[_callback] , либо (лучше, новый в 1.0.2) SSL_[CTX_]set_ecdh_auto(nonzero) . (Установите SSL_CTX перед SSL_new или SSL после.) (В 1.1.x он автоматически использует эквивалент ecdh_auto(true) .)

2. Кстати, важен не тип подписи в сертификате, а тип ключа В сертификате и (должен совпадать) privatekey. Часто это одно и то же, но это не обязательно. Также имеет значение KeyUsage, как и некоторые другие атрибуты / расширения сертификата.

3. Это работает, спасибо. Все, что я сделал, это добавил SSL_CTX_set_ecdh_auto(CTX, 0);

4. Могу ли я задать один дополнительный вопрос, я пытаюсь одновременно поддерживать как RSA, так и DSA, я попытался объединить один ключ / сертификат DSA в ключ / сертификат RSA, но по-прежнему обнаруживается только RSA, есть ли другие способы сделать это?