【问题标题】:Key generation requirements for TLS ECDHE-ECDSA-AES128-GCM-SHA256TLS ECDHE-ECDSA-AES128-GCM-SHA256 的密钥生成要求
【发布时间】:2012-04-17 04:36:15
【问题描述】:

我想知道 ECDHE-ECDSA-AES128-GCM-SHA256 和 ECDHE-ECDSA-AES128-GCM-SHA256 是否有最低密钥生成要求?我正在尝试使用上述算法之一让 TLS 客户端和服务器相互连接并继续接收“无共享密码错误”。我创建了一个 CA 来签署客户端和服务器证书,并尝试仅使用 openssl 以及 node.js 进行连接。我在 localhost (127.0.0.1) 上运行客户端和服务器以消除任何其他可能的问题。

这是我到目前为止所做的:

CA 密钥对创建:

  $ openssl genrsa -out ca-key.pem 4096
  $ openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem

服务器/客户端密钥对创建:

  $ openssl genrsa -out server-key.pem 4096
  $ openssl req -new -key server-key.pem -out server-csr.pem
  $ openssl x509 -req -days 365 -in server-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem 

  $ openssl genrsa -out client-key.pem 4096
  $ openssl req -new -key client-key.pem -out client-csr.pem
  $ openssl x509 -req -days 365 -in client-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 -out client-cert.pem

我最初试图从命令行连接到 node.js 服务器 (tls.createServer() 选项: ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256 '),但为了消除对节点的怀疑,我退回到 openssl 来创建客户端和服务器。

以下命令正确连接客户端和服务器,并声明它使用的密码为“New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384”:

$ openssl s_server -accept 8888 -cert server-cert.pem -key server-key.pem -pass stdin -CAfile ca-cert.pem  -state
<password entered here>

$ openssl s_client -connect 127.0.0.1:8888 -cert client-cert.pem -key client-key.pem -pass stdin -CAfile ca-cert.pem -state
<password entered here>

共享密码信息如下:

Shared ciphers:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-R
SA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES2
56-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-DSS-AES256-GCM-SHA384
:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-A
ES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECD
H-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:AES256-GCM-SHA384
:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES
-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA
:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA
:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA2
56:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS
-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-DSS-AES128-GCM-SHA256

当我在服务器或客户端和服务器上指定密码时,以下命令不起作用。请注意,ECDHE-ECDSA-AES128-GCM-SHA256 密码在上述列表中列为共享。

$ openssl s_server -accept 8888 -cert server-cert.pem -key server-key.pem -pass stdin -CAfile ca-cert.pem -cipher ECDHE-ECDSA-AES128-GCM-SHA256
<password entered here>

<< Server output after client connection attempt >>
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
ERROR
2674688:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1353:
shutting down SSL
CONNECTION CLOSED
ACCEPT


$ openssl s_client -connect 127.0.0.1:8888 -cert client-cert.pem -key client-key.pem -pass stdin -CAfile ca-cert.pem -cipher ECDHE-ECDSA-AES128-GCM-SHA256
<password entered here>

<<client output after connection attempt>>
CONNECTED(00000003)
2674688:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:708:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 166 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

有人有什么想法吗?提前致谢!

【问题讨论】:

  • 您使用的是什么版本的 openssl? openssl 版本
  • 我正在使用 OpenSSL 1.0.1 2012 年 3 月 14 日
  • 还要确保使用“命名曲线”。有关详细信息,请参阅 OpenSSL wiki 上的Elliptic Curve Cryptography | Named Curves

标签: node.js cryptography openssl


【解决方案1】:

您使用

制作了错误类型的密钥
 openssl genrsa -out ca-key.pem 4096 

你需要使用ecparam

openssl ecparam -name secp521r1 -out ca-key.pem -genkey

openssl ecparam -name secp521r1 -out client-key.pem -genkey

genrsa 生成一个 RSA 密钥,当与 ECDHE 一起使用时,它会验证椭圆曲线 Diffie Hellman 密钥交换 (ECDHE)。

ECDHE-ECDSA-AES128-GCM-SHA256 中的 ECDSA 意味着您需要椭圆曲线数字签名算法来验证该密钥。因为您没有这些密钥,所以命令失败。但是,ECDHE-RSA-AES256-GCM-SHA384 可以工作,因为它使用您拥有的 RSA 密钥。

您得到 sha384 是因为 openssl 选择了最强的密码套件,并且在所有条件相同的情况下,sha384 优于 sha256。您可以覆盖它,看起来您使用 --cipher 这样做了。

请注意,您可能想要使用不同的曲线。您可以使用

获取完整列表
openssl ecparam -list_curves

出于好奇,为什么要使用特定的密码套件? ECDHE 和 ECDSA 是最先进的,但 sha256 只是标准,而且 AES 128 肯定足够好,如果人们像 ECDHE 和 ECDSA 所暗示的那样谨慎,他们倾向于使用 256。

【讨论】:

  • 谢谢!这让我走上了正确的轨道。 :D 我选择了那些与RFC 6460 匹配的密码套件,并且应该在“可接受的曲线”部分分别指定使用 secp256r1 或 secp384r1。为了进一步参考,我将发布我在 openssl 中使用的命令。我还必须设置 examples 部分中列出的 demoCA 目录及其内容。
  • 我用这个Elliptic Curve CA guide 来做openssl 例子来签署密钥。我必须先创建CA examples 中提到的目录,然后才能签署任何内容。我使用以下命令进行测试:openssl s_server -accept 8888 -cert server.cert -key server.key -pass stdin -CAfile ca.cert -cipher ECDHE-ECDSA-AES128-GCM-SHA256openssl s_client -connect 127.0.0.1:8888 -cert client.cert -key client.key -pass stdin -CAfile ca.cert -cipher ECDHE-ECDSA-AES128-GCM-SHA256
  • Nitpick:对于 ECDHE-ECDSA,服务器密钥和客户端密钥(如果此处使用客户端身份验证)必须是 ECC。 CA 密钥不需要是 ECC,RSA 仍然有效。但良好的做法是,任何 CA 密钥都应该至少与在其下签名的密钥一样,因此(最小)ECC 256 要求 RSA>=3072 使用 NIST 的等效项。
  • @dave_thompson_085 Nitpick^2:对于 ECDHE-ECDSA 密码,客户端密钥/证书可以是 RSA。对于 RSA 密码,客户端密钥/证书可以是 ECDSA。 在服务器上 的验证阶段只期望获得可信证书,不一定使用相同的密码。如您所述,在客户端的验证阶段更加严格。
  • @kubanczyk:你是对的;那天我一定是产生了幻觉。客户端 EE 证书和密钥类型仅受 CertificateRequest 约束。并且增加一个皱纹:在 TLS1.2 中,现在使用比 2012 年更多,来自服务器的 chain/CA 证书受 ClientHello 中的 signature_algorithms 约束,并且通过 CertificateRequest 中的类似字段来自客户端,但在这两种情况下不是通过密码套件。
猜你喜欢
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 2017-03-02
  • 2015-12-18
  • 1970-01-01
相关资源
最近更新 更多