Нет доступных шифров для конкретного сертификата ECDSA

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

Проблема кажется, что для этого сертификата нет шифра. Чтобы проверить все это, я использовал openssl s_server на стороне сервера и скрипт nmap ssl-enum-ciphers на стороне клиента. nmap возвращает пустой список шифров.

Команда, данная для сервера:

openssl s_server -accept 4433 -cert server1.crt -certform PEM -key server1.key

это сертификат, который я использую на стороне сервера.

Certificate:
Data:
    Version: 3 (0x2)
    Serial Number: 256 (0x100)
Signature Algorithm: ecdsa-with-SHA256
    Issuer: C=IT, O=wwwtech, CN=wwwtech Server CA
    Validity
        Not Before: Jul 17 12:11:31 2017 GMT
        Not After : Jul 17 12:11:31 2019 GMT
    Subject: C=IT, O=wwwtech, CN=server1
    Subject Public Key Info:
        Public Key Algorithm: id-ecPublicKey
            Public-Key: (160 bit)
            pub: 
                04:1c:e3:02:ec:bc:0f:88:7a:58:0b:36:b6:55:2c:
                e5:f1:67:5f:a0:7a:c3:c9:4b:7c:45:02:42:61:20:
                0c:4d:30:22:f6:c7:09:b5:ef:e1:8e
            ASN1 OID: brainpoolP160r1
    X509v3 extensions:
        X509v3 Basic Constraints: 
            CA:FALSE
        X509v3 Key Usage: 
            Key Encipherment
        Netscape Cert Type: 
            SSL Server
        Netscape Comment: 
            AreaWFI Server Certificate
        X509v3 Subject Key Identifier: 
            8D:92:1A:9F:6A:AB:D2:E5:6B:72:CB:25:A9:15:27:38:08:CE:DE:A9
        X509v3 Authority Key Identifier: 
            keyid:E7:2F:0E:A7:39:B4:85:46:FE:2A:EA:9F:0A:FE:54:F4:B9:A5:B6:AC

        X509v3 Subject Alternative Name: 
            IP Address:127.0.0.1
Signature Algorithm: ecdsa-with-SHA256
     30:44:02:20:32:f1:d1:90:08:f1:dc:a5:9d:30:d3:db:4b:05:
     6c:d2:41:cc:ac:6f:01:f8:90:0d:a5:25:27:4d:f9:38:62:14:
     02:20:19:37:c4:7c:07:e9:07:2d:c8:6e:1f:a4:db:4e:44:48:
     68:4a:e9:9d:03:68:b3:b0:c6:31:60:92:ed:54:5c:22

person Luca Rizzuti    schedule 18.07.2017    source источник


Ответы (2)


Ваш сертификат использует кривую brainpoolP160r1. Эта кривая поддерживается libcrypto, но не libssl. Вероятно, потому что это недостаточно безопасно (он предлагает только эквивалент 80 бит безопасности). Вероятно, если вы попробуете другую (более безопасную) кривую, вы получите лучшие результаты.

Вы не говорите, какую версию OpenSSL вы используете. Обратите внимание, что в OpenSSL 1.1.0 кривые «по умолчанию», поддерживаемые OpenSSL, — это X25519, P-256, P-384 и P-512. Если вы хотите использовать другие кривые, вам, вероятно, придется указать их явно, используя параметр "-curves" для s_server. Единственные кривые пула мозгов, которые libssl поддерживает в OpenSSL 1.1.0, — это brainpoolP256r1, brainpoolP384r1 и brainpoolP512r1.

Изменить:

Я также отмечаю, что у вас есть использование ключа X509v3 «Ключевое шифрование», которое не имеет никакого смысла для сертификата ECDSA (ECDSA не может ничего «зашифровать»; это алгоритм цифровой подписи). Измените использование ключа на «Цифровая подпись» (или вообще отмените его).

person Matt Caswell    schedule 18.07.2017
comment
Я использую OpenSSL 1.0.2g. Я думал, что brainpoolP160r1 поддерживается, потому что openssl ecparam -list_curves отображает его. Спасибо большое. - person Luca Rizzuti; 18.07.2017
comment
Эта опция ecparam перечисляет все кривые, поддерживаемые libcrypto, что значительно длиннее списка, поддерживаемого libssl. Не все кривые считаются подходящими для использования SSL/TLS. В 1.0.2g список кривых по умолчанию libssl длиннее, чем в 1.1.0. Он включает в себя P-256, P-384, P-512, а также кривые мозга аналогичного размера и несколько разных, редко используемых, других. Полный список поддерживаемых кривых в 1.0.2g (которые вы должны включить с помощью -curves) довольно длинный список, но до сих пор не включает brainpoolP160r1. - person Matt Caswell; 18.07.2017
comment
Полный список кривых, поддерживаемых в libssl версии 1.0.2, находится здесь: github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/ssl/ - person Matt Caswell; 18.07.2017
comment
Я пробовал с кривой Prime256v1 (предложенной openssl вместо secp256r1 ), но безуспешно. nmap ничего не отображает, и если я попытаюсь подключить s_server с помощью переключателя -www в браузере, я получу SSL_ERROR_NO_CYPHER_OVERLAP. - person Luca Rizzuti; 18.07.2017
comment
Prime256v1 и secp256r1 являются синонимами. Однако я отмечаю, что ваш исходный сертификат имеет очень странную настройку использования ключа. Если ваш новый сертификат на основе P-256 имеет ту же настройку, то это будет проблематично. Я обновил свой ответ этой информацией. - person Matt Caswell; 18.07.2017
comment
Я использовал RFC 5280 в качестве эталона для использования ключей и основных ограничений. Возможно, я неправильно интерпретировал RFC. - person Luca Rizzuti; 18.07.2017
comment
@LucaRizzuti Я думаю, что RFC 5639 более уместно ссылаться на - person YusufUMS; 25.02.2020

Задача решена. Я заменил brainpoolP160r1 на Prime256v1 и удалил keyUsage=KeyEncipherment из openssl.conf подписывающего ЦС, после чего он начал работать как положено. Теперь я думаю, почему? В разделе 4.2.1.3 RFC 5280 говорится:

Бит keyEncipherment устанавливается, когда открытый ключ субъекта используется для шифрования закрытых или секретных ключей, т. е. для передачи ключей. Например, этот бит должен быть установлен, когда открытый ключ RSA должен использоваться для шифрования симметричного ключа дешифрования содержимого или асимметричного закрытого ключа.

Это происходит во время рукопожатия ssl или нет?

person Luca Rizzuti    schedule 18.07.2017
comment
Рад, что у вас все получилось (пожалуйста, не могли бы вы отметить мой ответ как правильный?). Сертификаты RSA и ECDSA в SSL/TLS работают по-разному. С сертификатом RSA клиент выбирает ключ и шифрует его с помощью открытого ключа. Таким образом, настройка Key Encipherment является правильной для RSA. ECDSA не используется таким образом. Вместо этого он используется вместе с ECDHE. ECDHE является алгоритмом согласования ключей, т.е. оба одноранговых узла взаимно вычисляют общий секрет, но сам ключ никогда не отправляется по сети. ECDSA используется сервером для цифровой подписи рукопожатия в целях аутентификации. Следовательно, шифрование ключей не подходит для ECDSA. - person Matt Caswell; 19.07.2017