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 位:
- "...ed25519 私钥的长度定义为 32- 位。来自...的第 5.1.5 节"
- "...私钥是32个八位字节(256位,对应b)..."
- "...这显示了一个长度为 32 字节 的私钥,符合预期...."
- "...然而底线是,ed25519 私钥始终是 32 位,您无法更改它...."
我需要使用 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 位:
- "...ed25519 私钥的长度定义为 32- 位。来自...的第 5.1.5 节"
- "...私钥是32个八位字节(256位,对应b)..."
- "...这显示了一个长度为 32 字节 的私钥,符合预期...."
- "...然而底线是,ed25519 私钥始终是 32 位,您无法更改它...."