Точный байтовый формат ключа ed25519, созданного openssl - PullRequest
1 голос
/ 04 августа 2020

Кто-нибудь знает или может указать, намекнет мне на ресурсы, где это задокументировано?

Я хочу, чтобы информация была примерно такой:

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. Во-вторых, формат ключа открывает sh выглядит совершенно другим.

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Ключи 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
1 голос
/ 04 августа 2020

Хорошо, в основном предварительным условием является понимание ASN.1

ASN.1 - это спецификация абстрактного синтаксиса, описывающего структуру данных. Это рекурсивно и сложно. И что меня интересует, так это точная структура данных, определяемая им, а не синтаксисом.

Итак, простое верхнее представление любого перевариваемого токена:

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

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

Type.class определяется как mean

  • 00: UNIVERSAL, универсально допустимый тип
  • 01: APPLICATION, тип, определяемый приложением c
  • 10: Context-specifici c
  • 11: ЧАСТНЫЙ

Только УНИВЕРСАЛЬНЫЙ класс соответствует отображаемой структуре. Другие классы могут полностью переопределить все.

Type.form определяется как

  • 0: примитив, например INTEGER
  • 1: построено, например SEQUENCE

Type.tag означает

  • 0x00: EO C
  • 0x01: BOOLEAN
  • 0x02: INTEGER
  • 0x03: BIT_STRING
  • 0x04: OCTET_STRING
  • 0x05: NULL
  • 0x06: OBJECT_IDENTIFIER
  • 0x07: ObjectDescriptor
  • 0x05 ВНЕШНИЙ
  • 0x09: REAL
  • 0x0A: ENUMERATED
  • 0x0B: EMBEDDED_PDV
  • 0x0 C: UTF8String
  • 0x10: SEQUENCE
  • 0x11: SET
  • 0x12: NumericString
  • 0x13: PrintableString
  • 0x14: TeletexString
  • 0x15: VideotexString ";
  • 0x16: IA5String
  • 0x17: UTCTime
  • 0x18: GeneralizedTime
  • 0x19: GraphicString
  • 0x1A: VisibleString
  • 0x1B: GeneralString
  • 0x1 C : UniversalString
  • 0x1E: BMPString

Длина может быть определена

  • Short -> при определении как примитив -> первый бит равен 0, остальные 7 бит определяют значение
  • Long -> при определении как Primitive -> первый бит равен 1, остальные 7 битов определяют длину следующего значения длины
  • Indefinite -> здесь значение длины заканчивается двумя нулями байт
...