OpenSSL EdDSA 指定密钥大小

OpenSSL EdDSA Specify Key Size

我需要使用 ed25519 曲线为我正在处理的项目的 NodeJS elliptic 模块生成一些密钥对。经过一番搜索,发现可以使用以下命令来完成:

openssl genpkey -algorithm ed25519 -out private.pem

但是,这始终会生成长度为 64 个字符的密钥。不过,我希望为密钥指定一个特定的大小。这可能使用 OpenSSL 吗?如果没有,能否请我指出一种方法,通过该方法可以在其他地方安全地生成具有设定大小的此类密钥?

此外,我对椭圆曲线密码学还很陌生,还不太了解 EdDSA 密钥是如何生成的。所以请告诉我我是否完全无法理解这一点,如果是的话,请解释我哪里出了大错。

ed25519 私钥的长度定义为 32 字节。来自 RFC8032 的第 5.1.5 节:

The private key is 32 octets (256 bits, corresponding to b) of
cryptographically secure random data. See [RFC4086] for a discussion about randomness.

我不知道你上面问题中的 64 个字符是从哪里来的。我可能认为您正在查看编码长度 - 但这也没有意义。

如果我这样做:

openssl genpkey -algorithm ed25519 -out private.pem

然后我得到一个长度为119字节的PEM编码私钥。这是根据 RFC8410 的第 7 节进行编码的。你可以这样看内容:

openssl asn1parse -in private.pem
    0:d=0  hl=2 l=  46 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :00
    5:d=1  hl=2 l=   5 cons: SEQUENCE          
    7:d=2  hl=2 l=   3 prim: OBJECT            :ED25519
   12:d=1  hl=2 l=  34 prim: OCTET STRING      [HEX DUMP]:0420F897797B25D84588192CE39F0E6311954034CB80F6D8CD648A3BCBFC2346A83E

实际的原始私钥本身被编码为 OCTET STRING inside 上面显示的 OCTET STRING(根据 RFC 8410)。正如您在上面看到的,八位字节字符串从偏移量 12 开始,header 长度为 2 - 因此数据本身位于偏移量 14:

openssl asn1parse -in private.pem -offset 14
    0:d=0  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:F897797B25D84588192CE39F0E6311954034CB80F6D8CD648A3BCBFC2346A83E

其中显示了一个长度为 32 字节的私钥,符合预期。

某些软件可能会以不符合 RFC8410 的不同格式存储密钥(例如,通过将私钥和 public 密钥存储在一起)- 因此,如果您已将此密钥加载到其他内容中,那么这可能会解释在哪里64来自。不过,您不能使用 OpenSSL 生成这些格式。

但最重要的是,ed25519 私钥始终为 32 字节,您无法更改它。它是算法的基础属性。

@arctic_hen7 你可能在这里指的是 32 字节 而不是 32 位:

  1. "...ed25519 私钥的长度定义为 32-。来自...的第 5.1.5 节"
  2. "...私钥是32个八位字节(256位,对应b)..."
  3. "...这显示了一个长度为 32 字节 的私钥,符合预期...."
  4. "...然而底线是,ed25519 私钥始终是 32 位,您无法更改它...."