>> Things I learned by looking at these 1024-bit RSA public key representations 
>> included:

*         ASN.1 uses byte-aligned Tag-Length-Value encodings.

*         The tags for SEQUENCE, OID, NULL, BIT STRING, and INTEGER are 
respectively 0x30, 0x06, 0x05, 0x03, and 0x02.

*         These Length values are encoded as follows:

o   159 - 0x81 0x9f

o   9 - 0x09

o   0 - 0x00

*         The OID 1.2.840.113549.1.1.1 is encoded in 9 bytes as 0x2a 0x86 0x48 
0x86 0xf7 0x0d 0x01 0x01 0x01.

*         The OID is followed by an ASN.1 NULL - 0x05 0x00.

*         The RSA Key is represented as an encapsulated bit field.

*         There is an apparently unused zero byte (the 22nd byte of the SPKI 
field in the RFC 7250 example) as the first byte of this bit field.

The ASN.1 BIT STRING is DER-encoded as:
|Tag|Len  |Value                                       |
|   |     |Unused-bit-count  Bits-paddeded-with-0-bits |
| 03| 818D| 00               30818902...                 |

For a BIT SRING, the value part of the tag-length-value starts with 1 byte that 
holds the number of unused bits in the last byte of the value.
As an example, the 7 bits 1110001 are DER-encoded as 03(tag) 02(length) 
01(unused bit count) E2(bits plus 1 unused bit)


*         The rest of the bit field contains concatenated representations of 
the modulus and the exponent as ASN.1 INTEGERs.

The modulus and exponent are encapsulated in a SEQUENCE (tag byte 0x30), not 
just concatenated.


*         The 1024 bit modulus is represented in 129 bytes, with the first byte 
being zero.

Integers are represented in 2's-complement to handle positive and negative 
integers. If the top bit of the first byte is 1 you have a negative integer. 
Hence, you need an extra leading 0x00 byte for some positive integers.

> RSA_2048_PREFIX = 
> "30820122300D06092A864886F70D01010105000382010F003082010A02820101";

There are plenty of "2048-bit RSA keys" where the modulus is actually 2047-bits 
long (multiply two 1024-bit primes and you get a 2048-bit or 2047-bit modulus). 
There is no extra leading 0x00 byte when DER-encoding a 2047-bit modulus. 
Consequently, concatenating a fixed prefix to build a DER-encoding is likely to 
cause interop bugs.


*         How are the OIDs in the table at 
http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#appendix-A 
represented as ASN.1 OID values?



Example: HS256   1.2.840.113549.2.9



Believe it or not, the first step to DER-encode an OID is to convert the first 
two numbers (1.2.) to a single number. Multiple the first by 40 and add the 
second: 1*40 + 2 = 42 = 0x2A (aren't standards great ;). Now 42 and the 
following four numbers are each represented with a variable-length encoding: 7 
bits per byte; 8th bit (most significant bit) indicates if there are more bytes 
to follow.

Example: 113549 = 6*2^14 + 119 * 2^7 + 13 => encoded in 3 bytes 86 F7 0D, which 
you can see in the middle of RSA_2048_PREFIX above.



P.S. The draft splits the number 113549 (and JCA labels) over two lines. Yuck. 
Might be better to put the XML DSIG uris in a separate table to avoid wrapping.



*         Is there always the apparently unused zero byte in the key 
representation or if not, when is it present and absent?

Whenever you put a whole number of bytes into a BIT STRING you get the 0x00 
byte as there are no unused bits.


--
James Manger
_______________________________________________
jose mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/jose

Reply via email to