问题描述
我正在使用RSA密码对证书进行签名,并使用 SSL_CTX_set_tmp_ecdh_callback ()api设置密钥交换的ECDH参数.服务器总是最终选择TLS_ECDHE_RSA_ *密码套件.如果我让客户端仅在clientHello中发送TLS_ECDH_ *密码套件,则服务器将断开连接,指出无共享密码".
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".
有人可以告诉我如何使服务器选择ECDHE_ *上的ECDH_ *密码吗?
Can someone tell me how to make a server choose a ECDH_* cipher over ECDHE_* ?
服务器如何决定我应该选择ECDH_ *密码而不是ECDHE_ *密码?
How is it that the server decides I should choose ECDH_* cipher over ECDHE_* ciphers ?
推荐答案
现在,将其移到就位的地方,并进行了足够的澄清,聚会结束了:
Now that this is moved where it's ontopic, and clarified enough, and the partying is over:
临时ECDH套件:使用临时ECDH密钥交换(ECDHE-*
)的TLS套件至少使用名义上的临时ECDH密钥,OpenSSL将其称为临时".通过1.0.2的OpenSSL具有4-6种设置这些密钥的方法:
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
或SSL_set_tmp_ecdh
设置(仅)要使用的曲线";确切地说,这是一个EC_GROUP
或正式的参数集",由基础场上的曲线方程式定义的实际曲线以及指定的基点组成,该基点在曲线上产生足够高阶和低辅因子的子组,但是在大多数情况下,我们会忽略此细节,而是将其称为曲线".然后,OpenSSL会在每次握手期间以及每次握手期间在该曲线上生成一个随机密钥.
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
或SSL_set_tmp_ecdh_callback
设置一个函数,该函数在每次握手时调用,可以设置特定的键,也可以设置曲线,然后OpenSSL会在该曲线上生成随机键.
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
或SSL_set_ecdh_auto
新增功能会导致OpenSSL在每次握手时根据客户端问候选择一条曲线,并在该曲线上生成随机密钥.
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.
请注意,每个使用ECDHE的密码套件还定义了服务器必须用于认证的具有匹配证书链的密钥类型:ECDHE-RSA
必须使用RSA密钥和证书,而ECDHE-ECDSA
必须使用ECDSA密钥和证书(或精确的EC密钥和ECDSA证书,因为相同的EC密钥可用于ECDSA,ECDH,ECIES等,但通常不应使用).可以使用多个密钥和证书对配置OpenSSL库,每种密钥和证书对之一,命令行s_server
可以使用-cert -key -dcert -dkey
加上两个SNI -cert2 -key2
来进行两个静态对,但是其他程序可能会也可能不会.
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.
但是,在1.1.0中,这些功能已删除,并且看起来OpenSSL 始终会执行以前的ecdh_auto
.
However, in 1.1.0 these functions are removed and it appears OpenSSL always does what was formerly ecdh_auto
.
静态ECDH套件:使用静态aka固定ECDH密钥交换(ECDH-*
)的TLS套件使用静态ECDH密钥,而不使用临时或临时ECDH密钥.由于它们不使用临时键,因此设置临时曲线或关键点所涉及的功能无关,也没有任何用处.相反,静态ECDH密钥必须在服务器的已配置密钥和证书对中,并且证书必须允许ECDH,即它不能具有排除keyAgreement
的keyUsage
.此外,在TLS 1.0和1.1中,配置的证书必须由CA使用与密码套件匹配的签名算法来签名:ECDH-ECDSA
密码套件必须使用由ECDSA CA签名的ECDH证书,而ECDH-RSA
密码套件必须使用ECDH证书.由RSA CA签名;请参阅 rfc4492第5.3节.对于TLS 1.2 rfc 5246第7.4.2节和 ECC的A.7 放宽了此要求,并允许 CA cert是客户端的signature_algorithms扩展名允许的任何算法.但是,在检查中,我发现OpenSSL并没有实现这种放松,因此我先前的评论中的一部分是错误的. 即使对于1.2,它也要求CA签名算法与密码套件匹配.
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.
此外,对于所有协议版本,密钥和(EE)证书必须使用受支持的曲线(受支持的曲线扩展),并且该证书必须以命名"形式表示该密钥(使用OID标识曲线而不是显式参数)和客户端在support_formats扩展中支持的点格式.使用OpenSSL客户端,这永远不会成为问题,因为它支持所有命名的曲线和点格式,并且在实践中证书不使用显式的曲线参数.
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.
因此可以通过OpenSSL获得静态ECDH:
Thus to get static ECDH with OpenSSL:
-
使用EC密钥(
SSL_[CTX_]use_PrivateKey*
)和匹配的证书(SSL_[CTX_]use_certificate[_chain]*
)配置服务器,该密钥允许keyAgreement并由CA使用RSA或ECDSA签名-与所有基于PK的密码套件一样,也进行配置客户验证证书所需的任何链式证书
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
使用ECDH-xyz
将xyz
是RSA
或匹配服务器证书上的CA签名
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
完全忽略ecdh_tmp
和ecdh_auto
... ,但1.1.0 除外,经检查,我发现它不再实现任何静态ECDH 或静态DH密码套件-即使采用静态- DH套件仍在密码手册中.这不在我可以找到的CHANGES文件中,并且我还没有时间浏览代码.
... 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.
这篇关于有人可以告诉我如何使服务器选择ECDHE_ *上的ECDH_ *密码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!