1

Does anyone know, or may point,hint me towards ressources where this is documented?

What I want is the information like:

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

The cruzial part would really be the bytes and what the separators are, so I could parse it manually.

Actually I would be most happy to have just the information about all the formats. Because the first concern now is the openssl key-format. Secondly the openssh key format appears to be totally different.

Lenny
  • 157
  • 1
  • 13

2 Answers2

1

Okay, basically prerequisite is to understand ASN.1

ASN.1 is a specification for an abstract synthax describing a datastructure. It is recursive and complex. And what I am interested in is the exact datastructure defined by it rather than the synthax.

So the simple top representation of any digestable token is:

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

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

Type.class is defined to mean

  • 00: UNIVERSAL, a type which is universally valid
  • 01: APPLICATION, a type which is application specific
  • 10: Context-specific
  • 11: PRIVATE

Only the UNIVERSAL class is conforming with the displayed structure. The other classes could totally redefine everything.

Type.form is defined to mean

  • 0: Primitive, like INTEGER
  • 1: Constructed, like SEQUENCE

Type.tag is defined to mean

  • 0x00: EOC
  • 0x01: BOOLEAN
  • 0x02: INTEGER
  • 0x03: BIT_STRING
  • 0x04: OCTET_STRING
  • 0x05: NULL
  • 0x06: OBJECT_IDENTIFIER
  • 0x07: ObjectDescriptor
  • 0x08: EXTERNAL
  • 0x09: REAL
  • 0x0A: ENUMERATED
  • 0x0B: EMBEDDED_PDV
  • 0x0C: 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
  • 0x1C: UniversalString
  • 0x1E: BMPString

Length may be defined

  • Short -> when defined as Primitive -> first bit is 0 other 7 bits define the value
  • Long -> when defined as Primitive -> first bit is 1 other 7 bits define the length of the following length value
  • Indefinite -> here the length value is terminated by 2 null bytes
Lenny
  • 157
  • 1
  • 13
1

OpenSSL Ed25519 keys are encoded according to 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

For further clarification there is a sample Key:

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
Lenny
  • 157
  • 1
  • 13
Matt Caswell
  • 8,167
  • 25
  • 28