Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should this spec define byte prefixes associated with ASN.1 RSA Keys? #42

Open
OR13 opened this issue Nov 16, 2021 · 3 comments
Open

Should this spec define byte prefixes associated with ASN.1 RSA Keys? #42

OR13 opened this issue Nov 16, 2021 · 3 comments

Comments

@OR13
Copy link
Contributor

OR13 commented Nov 16, 2021

Originally reported here: #41 (comment)

IMO, it's a nice to have, that would make is possible for some implementations to skip importing bulky ASN.1 libraries as @dlongley mentions.

@OR13 OR13 mentioned this issue Nov 16, 2021
@clehner
Copy link
Member

clehner commented Nov 17, 2021

I supposed that it would be simple (#41 (comment)), but the length encoding is more complex than I remembered.

The RSAPublicKey ASN.1 type is a sequence (array) containing two integers.
The specification for DER is ITU-T X.690 | ISO/IEC 8825-1. The length encoding is described on page 14 (8.1.3.3 - 8.1.3.5).
Each value in the data structure (the sequence, and each of the two integers) is encoded as tag-length-value. The tag for the sequence type is 0x30, and the tag for the integer type is 0x02 (putting aside "constructed" types which I don't think occur here.)

Looking at two example keys from multiformats/multicodec#233 (comment), the initial bytes are the following for a 2048-bit key:
30 82 01 0a 02 82 01 01 00
and the following for a 4096-bit key:
30 82 02 0a 02 82 02 01 00
Then the modulus follows (2048 or 4096 bits, respectively).
Then the exponent follows:
02 03 01 00 01.

Looking at what those byte values mean:
30 - tag for sequence
82 01 0a - length of sequence (266 - i.e. the rest of the data) OR 82 01 0a (522) for the 4096-bit example
02 - tag for integer
82 01 01 - length of integer (257) OR 82 02 01 (513)
00 - leading zero of the integer value (modulus)
... modulus (256 or 512 bytes)
02 - tag for integer
03 - length of integer (3)
01 00 01 - integer value 65537 (public exponent).

Length encoding is 1 byte if the length is <= 127, in which case the length is encoded in that byte ("short mode"). If the length is > 127, one byte with the high bit set encodes the number of following bytes in the lower 7 bits, and then is followed by that many bytes that encode the length ("long mode"). We see the short mode in this example in the length of the public exponent (0x03 = 3), while the long mode is used for the length of the modulus: 0x82 = high bit set, lower bits are 0x02 (2); following 2 bytes are 0x0101 (257) OR 0x0201 (513).

The leading zero for an integer value is supposed to be used if the high bit of the integer value is set, as the high bit otherwise would be interpreted as a sign bit (reference).

I assume this is too much complexity for this specification, but if it is desired to put this into code, I could try to do so.

@OR13
Copy link
Contributor Author

OR13 commented Nov 17, 2021

Imo, it is too much complexity for the specification, unless we do the same to all the other key representations.... It might be better to just point to a good source for this information from each key representation.

@clehner
Copy link
Member

clehner commented Mar 23, 2022

This was done in #45.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants