Can someone tell me how to make a server choose a ECDH_* cipher over ECDHE_*?

China☆狼群 提交于 2020-05-23 07:36:13

问题


I am using RSA cipher for signing the certificate and SSL_CTX_set_tmp_ecdh_callback() api to set the ECDH parameters for key-exchange. The server always ends up choosing TLS_ECDHE_RSA_* cipher suite. If i make the client send only TLS_ECDH_* cipher suites in the clientHello, the server breaks the connection stating "no shared cipher".

Can someone tell me how to make a server choose a ECDH_* cipher over ECDHE_* ?

How is it that the server decides I should choose ECDH_* cipher over ECDHE_* ciphers ?


回答1:


Now that this is moved where it's ontopic, and clarified enough, and the partying is over:

Ephemeral ECDH suites: TLS suites that use ephemeral ECDH key exchange (ECDHE-*) use at least nominally ephemeral ECDH keys, which OpenSSL calls 'temporary'. OpenSSL through 1.0.2 has 4-6 ways of setting these keys:

SSL_CTX_set_tmp_ecdh or SSL_set_tmp_ecdh set (only) the 'curve' to be used; to be exact this is an EC_GROUP or formally 'parameter set' that consists of an actual curve defined by a curve equation on an underlying field, plus a specified base point which generates a subgroup on the curve of sufficiently high order and low cofactor, but most of the time we ignore this detail and just call it a 'curve'. OpenSSL then generates a random key on that curve for and during each handshake.

SSL_CTX_set_tmp_ecdh_callback or SSL_set_tmp_ecdh_callback sets a function that is called during each handshake and can either set a specific key, or set a curve and OpenSSL generates a random key on that curve.

SSL_CTX_set_ecdh_auto or SSL_set_ecdh_auto new in 1.0.2 causes OpenSSL during each handshake to choose a curve based on the client hello, and generate a random key on that curve.

Note that each ciphersuite using ECDHE also defines the type of key with matching certificate chain the server must use to authenticate: ECDHE-RSA must use an RSA key&cert while ECDHE-ECDSA must use an ECDSA key&cert (or to be precise EC key and ECDSA cert, since the same EC key can be used for ECDSA, ECDH, ECIES, and more, but usually shouldn't). OpenSSL library can be configured with multiple key&cert pairs, one of each type, and commandline s_server can do two static pairs using -cert -key -dcert -dkey plus one for SNI -cert2 -key2, but other programs may or may not.

However, in 1.1.0 these functions are removed and it appears OpenSSL always does what was formerly ecdh_auto.

Static ECDH suites: TLS suites that use static aka fixed ECDH key exchange (ECDH-*) use a static ECDH key and do not use an ephemeral or temporary ECDH key. Since they do not use a temporary key, the functions involved in setting a temporary curve or key are irrelevant and have no useful effect. Instead the static ECDH key must be in the server's configured key and certificate pair, and the certificate must allow ECDH i.e. it must not have keyUsage that excludes keyAgreement. In addition, in TLS 1.0 and 1.1 the configured certificate must be signed by a CA using a signature algorithm matching the ciphersuite: ECDH-ECDSA ciphersuites must use an ECDH cert signed by an ECDSA CA, and ECDH-RSA ciphersuites must use an ECDH cert signed by an RSA CA; see rfc4492 section 5.3. For TLS 1.2 rfc 5246 section 7.4.2 and A.7 for ECC relaxes this requirement and allows the CA cert to be any algorithm permitted by the client's signature_algorithms extension. However on checking I found OpenSSL doesn't implement this relaxation, so part of my earlier comment is wrong; even for 1.2 it requires the CA signature algorithm match the ciphersuite.

In addition for all protocol versions the key and (EE) cert must use a curve supported by the client in supported_curves extension, and the cert must express that key in 'named' form (using an OID to identify the curve rather than explicit parameters) and a point format supported by the client in supported_formats extension. With OpenSSL client this is never an issue because it supports all named curves and point formats, and in practice certificates don't use explicit curve parameters.

Thus to get static ECDH with OpenSSL:

  • configure the server with an EC key (SSL_[CTX_]use_PrivateKey*) and matching certificate (SSL_[CTX_]use_certificate[_chain]*) that allows keyAgreement and is signed by a CA using RSA or ECDSA -- and like all PK-based ciphersuites also configure any chain certs needed by the client(s) to validate the cert

  • configure both ends to allow (which is true by default) and at least one end to require or the preference end to prefer ciphersuite(s) using ECDH-xyz where xyz is RSA or ECDSA to match the CA signature on the server cert

  • ignore ecdh_tmp and ecdh_auto entirely

... except in 1.1.0, which on checking I found no longer implements any static-ECDH or static-DH ciphersuites -- even though the static-DH suites are still in the manpage for ciphers. This is not in the CHANGES file that I can find, and I haven't had time to go through the code yet.




回答2:


... except in 1.1.0, which on checking I found no longer implements any static-ECDH or static-DH ciphersuites -- even though the static-DH suites are still in the manpage for ciphers. This is not in the CHANGES file that I can find, and I haven't had time to go through the code yet.

https://github.com/openssl/openssl/commit/ce0c1f2bb2fd296f10a2847844205df0ed95fb8e



来源:https://stackoverflow.com/questions/41356625/can-someone-tell-me-how-to-make-a-server-choose-a-ecdh-cipher-over-ecdhe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!