1
$\begingroup$

I'm trying to encode an Ed25519 private key as a PEM file based on this document https://tools.ietf.org/html/rfc8410#page-7 .

I'm using an ASN.1 encoder written in Dart, and I can encode the private key without its public key and attributes as in this example:

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC
-----END PRIVATE KEY-----

But I can't make sense of the specification on how to encode the public key and attributes like this one:

-----BEGIN PRIVATE KEY-----
MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC
oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB
Z9w7lshQhqowtrbLDFw4rXAxZuE=
-----END PRIVATE KEY------

Using the lapo.it ASN.1 decoder you can see the optional fields, but I can't recreate it. What does the 0 and 1 mean? And why it doesn't have the annotated type?

$\endgroup$
2
$\begingroup$

This is more about representation and manipulation of data in a computer program than cryptography. Questions about Dart or the use of libraries in Dart, are better asked on Stackoverflow.

The [0] and [1] are context-specific tags; more exactly they are tags that are not universal (because then the number-type mapping would be fixed and known) with a class that is not specified and thus defaults to context-specific.

Because they are IMPLICIT, the top-level ASN.1 type of their contents is not encoded, and cannot be shown by a generic decoder like the one you link -- see a page earlier, above the table of universal types.

[0] is Attributes which in rfc5958 (and many other places) is SET OF Attribute (with infoset constraint) where CMS-style Attribute is SEQUENCE { attrType OBJECT IDENTIFIER, attrValue SET OF ANY --DEFINED BY type-- } in the old ASN.1 notation, or with attrValue defined by an infoset in the new notation. Thus the decode of [0] shows the one SEQUENCE of OID plus SET containing UTF8STRING.

On the other hand, [1] is PublicKey ::= BIT STRING which has no internal structure, so it is shown as raw data -- including the prefixed value octet for unused_bits = 00, so the real value of the publickey is the remaining 32 octets.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.