有人能告诉我如何让服务器选择 ECDHE_* 上的 ECDH_* 密码吗?
Can someone tell me how to make a server choose a ECDH_* cipher over ECDHE_*?
我正在使用 RSA 密码为证书签名,并使用 SSL_CTX_set_tmp_ecdh_callback() api 为密钥交换设置 ECDH 参数。服务器总是最终选择 TLS_ECDHE_RSA_* 密码套件。如果我让客户端在 clientHello 中仅发送 TLS_ECDH_* 密码套件,服务器会断开连接并声明 "no shared cipher".
有人能告诉我如何让服务器选择 ECDH_* 密码而不是 ECDHE_* 密码吗?
服务器如何决定我应该选择 ECDH_* 密码而不是 ECDHE_* 密码?
既然这已经转移到了主题上,并且已经足够清楚,聚会就结束了:
临时 ECDH 套件: 使用临时 ECDH 密钥交换 (ECDHE-*
) 的 TLS 套件至少使用名义上临时 ECDH 密钥,OpenSSL 调用 'temporary' . OpenSSL 到 1.0.2 有 4-6 种设置这些键的方法:
SSL_CTX_set_tmp_ecdh
或 SSL_set_tmp_ecdh
设置(仅)要使用的 'curve';确切地说,这是一个 EC_GROUP
或正式的 'parameter set',它由一个由基础字段上的曲线方程定义的实际曲线,加上一个指定的基点组成,该基点在足够高阶的曲线上生成一个子群和低辅因子,但大多数时候我们忽略了这个细节,只是称它为 'curve'。然后,OpenSSL 在每次握手期间以及在该曲线上生成一个随机密钥。
SSL_CTX_set_tmp_ecdh_callback
或 SSL_set_tmp_ecdh_callback
设置每次握手期间调用的函数,可以设置特定密钥,或设置曲线,OpenSSL 在该曲线上生成随机密钥。
SSL_CTX_set_ecdh_auto
或 SSL_set_ecdh_auto
1.0.2 中的新增功能导致 OpenSSL 在每次握手期间根据客户端问候选择一条曲线,并在该曲线上生成一个随机密钥。
请注意,每个使用 ECDHE 的密码套件还定义了服务器必须用于身份验证的具有匹配证书链的密钥类型:ECDHE-RSA
必须使用 RSA 密钥和证书,而 ECDHE-ECDSA
必须使用 ECDSA 密钥和证书(或者准确地说是 EC 密钥和 ECDSA 证书,因为相同的 EC 密钥可用于 ECDSA、ECDH、ECIES 等,但通常不应该使用)。 OpenSSL 库可以配置多个密钥和证书对,每种类型一个,命令行 s_server
可以使用 -cert -key -dcert -dkey
做两个静态对加上一个用于 SNI -cert2 -key2
,但其他程序可能会也可能不会.
但是,在 1.1.0 中,这些功能被删除了,而且 OpenSSL 总是 执行以前 ecdh_auto
.
的操作
静态 ECDH 套件: 使用静态又名固定 ECDH 密钥交换 (ECDH-*
) 的 TLS 套件使用静态 ECDH 密钥,不使用临时或临时 ECDH钥匙。由于它们不使用临时键,因此设置临时曲线或键所涉及的功能是无关紧要的,没有任何用处。相反,静态 ECDH 密钥必须 在服务器配置的密钥和证书对 中,并且证书必须允许 ECDH,即它不能有排除 keyAgreement
的 keyUsage
。此外,在 TLS 1.0 和 1.1 中,配置的证书必须由 CA 使用与密码套件匹配的签名算法进行签名:ECDH-ECDSA
密码套件必须使用由 ECDSA CA 签名的 ECDH 证书,并且 ECDH-RSA
密码套件必须使用由 RSA CA 签名的 ECDH 证书;请参阅 rfc4492 section 5.3. For TLS 1.2 rfc 5246 section 7.4.2 and A.7 for ECC 放宽此要求并允许 CA 证书是客户端 signature_algorithms 扩展允许的任何算法。但是在检查时我发现 OpenSSL 没有实现这种放松,所以我之前的部分评论是错误的; 即使是 1.2,它也需要 CA 签名算法匹配密码套件。
此外,对于所有协议版本,密钥和 (EE) 证书必须使用 supported_curves 扩展中客户端支持的曲线,并且证书必须以 'named' 形式表示该密钥(使用一个 OID 来识别曲线而不是显式参数)和客户端在 supported_formats 扩展中支持的点格式。对于 OpenSSL 客户端,这从来都不是问题,因为它支持所有命名曲线和点格式,并且实际上证书不使用显式曲线参数。
因此使用 OpenSSL 获取静态 ECDH:
使用 EC 密钥 (SSL_[CTX_]use_PrivateKey*
) 和匹配的证书 (SSL_[CTX_]use_certificate[_chain]*
) 配置服务器,该证书允许 keyAgreement 并由 CA 使用 RSA 或 ECDSA 签名 -- 和像所有基于 PK 的密码套件一样,还配置客户端验证证书所需的任何链证书
将两端配置为允许(默认情况下为真)并且至少要求一端或偏好端使用 ECDH-xyz
where xyz
是 RSA
或 ECDSA
以匹配服务器证书上的 CA 签名
完全忽略ecdh_tmp
和ecdh_auto
... 除了 1.1.0,在检查时我发现它不再实现任何静态 ECDH 或 静态 DH ciphersuites——尽管静态 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.
https://github.com/openssl/openssl/commit/ce0c1f2bb2fd296f10a2847844205df0ed95fb8e
我正在使用 RSA 密码为证书签名,并使用 SSL_CTX_set_tmp_ecdh_callback() api 为密钥交换设置 ECDH 参数。服务器总是最终选择 TLS_ECDHE_RSA_* 密码套件。如果我让客户端在 clientHello 中仅发送 TLS_ECDH_* 密码套件,服务器会断开连接并声明 "no shared cipher".
有人能告诉我如何让服务器选择 ECDH_* 密码而不是 ECDHE_* 密码吗?
服务器如何决定我应该选择 ECDH_* 密码而不是 ECDHE_* 密码?
既然这已经转移到了主题上,并且已经足够清楚,聚会就结束了:
临时 ECDH 套件: 使用临时 ECDH 密钥交换 (ECDHE-*
) 的 TLS 套件至少使用名义上临时 ECDH 密钥,OpenSSL 调用 'temporary' . OpenSSL 到 1.0.2 有 4-6 种设置这些键的方法:
SSL_CTX_set_tmp_ecdh
或 SSL_set_tmp_ecdh
设置(仅)要使用的 'curve';确切地说,这是一个 EC_GROUP
或正式的 'parameter set',它由一个由基础字段上的曲线方程定义的实际曲线,加上一个指定的基点组成,该基点在足够高阶的曲线上生成一个子群和低辅因子,但大多数时候我们忽略了这个细节,只是称它为 'curve'。然后,OpenSSL 在每次握手期间以及在该曲线上生成一个随机密钥。
SSL_CTX_set_tmp_ecdh_callback
或 SSL_set_tmp_ecdh_callback
设置每次握手期间调用的函数,可以设置特定密钥,或设置曲线,OpenSSL 在该曲线上生成随机密钥。
SSL_CTX_set_ecdh_auto
或 SSL_set_ecdh_auto
1.0.2 中的新增功能导致 OpenSSL 在每次握手期间根据客户端问候选择一条曲线,并在该曲线上生成一个随机密钥。
请注意,每个使用 ECDHE 的密码套件还定义了服务器必须用于身份验证的具有匹配证书链的密钥类型:ECDHE-RSA
必须使用 RSA 密钥和证书,而 ECDHE-ECDSA
必须使用 ECDSA 密钥和证书(或者准确地说是 EC 密钥和 ECDSA 证书,因为相同的 EC 密钥可用于 ECDSA、ECDH、ECIES 等,但通常不应该使用)。 OpenSSL 库可以配置多个密钥和证书对,每种类型一个,命令行 s_server
可以使用 -cert -key -dcert -dkey
做两个静态对加上一个用于 SNI -cert2 -key2
,但其他程序可能会也可能不会.
但是,在 1.1.0 中,这些功能被删除了,而且 OpenSSL 总是 执行以前 ecdh_auto
.
静态 ECDH 套件: 使用静态又名固定 ECDH 密钥交换 (ECDH-*
) 的 TLS 套件使用静态 ECDH 密钥,不使用临时或临时 ECDH钥匙。由于它们不使用临时键,因此设置临时曲线或键所涉及的功能是无关紧要的,没有任何用处。相反,静态 ECDH 密钥必须 在服务器配置的密钥和证书对 中,并且证书必须允许 ECDH,即它不能有排除 keyAgreement
的 keyUsage
。此外,在 TLS 1.0 和 1.1 中,配置的证书必须由 CA 使用与密码套件匹配的签名算法进行签名:ECDH-ECDSA
密码套件必须使用由 ECDSA CA 签名的 ECDH 证书,并且 ECDH-RSA
密码套件必须使用由 RSA CA 签名的 ECDH 证书;请参阅 rfc4492 section 5.3. For TLS 1.2 rfc 5246 section 7.4.2 and A.7 for ECC 放宽此要求并允许 CA 证书是客户端 signature_algorithms 扩展允许的任何算法。但是在检查时我发现 OpenSSL 没有实现这种放松,所以我之前的部分评论是错误的; 即使是 1.2,它也需要 CA 签名算法匹配密码套件。
此外,对于所有协议版本,密钥和 (EE) 证书必须使用 supported_curves 扩展中客户端支持的曲线,并且证书必须以 'named' 形式表示该密钥(使用一个 OID 来识别曲线而不是显式参数)和客户端在 supported_formats 扩展中支持的点格式。对于 OpenSSL 客户端,这从来都不是问题,因为它支持所有命名曲线和点格式,并且实际上证书不使用显式曲线参数。
因此使用 OpenSSL 获取静态 ECDH:
使用 EC 密钥 (
SSL_[CTX_]use_PrivateKey*
) 和匹配的证书 (SSL_[CTX_]use_certificate[_chain]*
) 配置服务器,该证书允许 keyAgreement 并由 CA 使用 RSA 或 ECDSA 签名 -- 和像所有基于 PK 的密码套件一样,还配置客户端验证证书所需的任何链证书将两端配置为允许(默认情况下为真)并且至少要求一端或偏好端使用
ECDH-xyz
wherexyz
是RSA
或ECDSA
以匹配服务器证书上的 CA 签名完全忽略
ecdh_tmp
和ecdh_auto
... 除了 1.1.0,在检查时我发现它不再实现任何静态 ECDH 或 静态 DH ciphersuites——尽管静态 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.
https://github.com/openssl/openssl/commit/ce0c1f2bb2fd296f10a2847844205df0ed95fb8e