openssl 生成的 ed25519 密钥的精确字节格式

Posted

技术标签:

【中文标题】openssl 生成的 ed25519 密钥的精确字节格式【英文标题】:Exact byte format of ed25519 key generated by openssl 【发布时间】:2020-11-24 03:31:39 【问题描述】:

有没有人知道,或者可能会指出,提示我找到记录此内容的资源?

我想要的是这样的信息:

PrivateKeyInfo ::= SEQUENCE 
  version         Version, (1byte)
  algorithm       AlgorithmIdentifier,(2byte)
  PrivateKey      OCTET STRING (xbyte)


AlgorithmIdentifier ::= SEQUENCE 
  algorithm       OBJECT IDENTIFIER, (1byte)
  parameters      ANY DEFINED BY algorithm OPTIONAL (ybyte)

// separators are encoded as 0

真正关键的部分是字节和分隔符是什么,所以我可以手动解析它。

实际上,如果我能获得有关所有格式的信息,我会非常高兴。 因为现在首先关心的是 openssl 密钥格式。其次,openssh 密钥格式似乎完全不同。

【问题讨论】:

【参考方案1】:

OpenSSL Ed25519 密钥根据 RFC8410 进行编码:

   OneAsymmetricKey ::= SEQUENCE 
      version Version,
      privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
      privateKey PrivateKey,
      attributes [0] IMPLICIT Attributes OPTIONAL,
      ...,
      [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
      ...
   

   PrivateKey ::= OCTET STRING

   PublicKey ::= BIT STRING

   For the keys defined in this document, the private key is always an
   opaque byte sequence.  The ASN.1 type CurvePrivateKey is defined in
   this document to hold the byte sequence.  Thus, when encoding a
   OneAsymmetricKey object, the private key is wrapped in a
   CurvePrivateKey object and wrapped by the OCTET STRING of the
   "privateKey" field.

   CurvePrivateKey ::= OCTET STRING

为了进一步说明,有一个示例密钥:

30 2E 02 01 00 30 05 06  03 2B 65 70 04 22 04 20
5F E5 F1 D9 02 D6 B4 2E  55 B6 E4 E4 01 E9 87 C3
F2 BC 7F 95 D3 31 88 86  3D E9 17 60 B7 D5 84 92

30 2E => SEQUENCE of 3 Elements having length of 46
02 01 00 => INTEGER of length 1 being 00 (Version)
30 05 => SEQUENCE of 1 Element having length of 5
06  03 2B 65 70 => OBJECT IDENTIFIER of length 3 being 2B 65 70 (PrivateKeyAlgorithmIdentifier)
04 22 => OCTET STRING of Length 34
04 20 => OCTET STRING of Length 32
Value of the real OCTET STRING (PrivateKey):
5F E5 F1 D9 02 D6 B4 2E  55 B6 E4 E4 01 E9 87 C3
F2 BC 7F 95 D3 31 88 86  3D E9 17 60 B7 D5 84 92

【讨论】:

【参考方案2】:

好的,基本前提是了解ASN.1

ASN.1 是描述数据结构的抽象语法规范。 它是递归的和复杂的。我感兴趣的是它定义的确切数据结构,而不是合成器。

所以任何可消化标记的简单顶部表示是:

|Type(1byte)|Length(1-xbyte)|Value(ybyte)|

Type: |class(2bit)|form(1bit)|tag(5bit)|

Type.class 被定义为意味着

00:UNIVERSAL,一种普遍有效的类型 01:APPLICATION,一种特定于应用程序的类型 10:特定于上下文 11:私人

只有 UNIVERSAL 类符合显示的结构。 其他类可以完全重新定义一切。

Type.form 被定义为意味着

0:基元,如 INTEGER 1:构造,如 SEQUENCE

Type.tag 被定义为意味着

0x00:EOC 0x01:布尔值 0x02:整数 0x03:BIT_STRING 0x04:OCTET_STRING 0x05:空 0x06:OBJECT_IDENTIFIER 0x07:对象描述符 0x08:外部 0x09:真实 0x0A:枚举 0x0B:EMBEDDED_PDV 0x0C: UTF8String 0x10:序列 0x11:设置 0x12:数字字符串 0x13:可打印字符串 0x14: TeletexString 0x15: VideotexString"; 0x16: IA5String 0x17:UTC 时间 0x18:广义时间 0x19:图形字符串 0x1A:可见字符串 0x1B:通用字符串 0x1C:通用字符串 0x1E:BMPString

长度可以定义

短 -> 定义为 Primitive -> 第一位为 0 其他 7 位定义值 Lo​​ng -> 当定义为 Primitive -> 第一位为 1 其他 7 位定义以下长度值的长度 不定 -> 这里长度值以 2 个空字节结束

【讨论】:

以上是关于openssl 生成的 ed25519 密钥的精确字节格式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Bouncy Castle 创建与 OpenSSH 兼容的 ED25519 密钥?

如何使用 ssh-ed25519 作为 pysftp 的密钥来设置主机密钥文件

使用ED25519算法生成SSH密钥,解决git clone报错:early EOF fetch-pack: invalid index-pack output

Linux 生成密钥

ANFS | ED25519密钥体系 技术一小步 行业发展一大步

Bytomd 助记词恢复密钥体验指南