> Okay, so why isn't it done consistently? Some tools report the leading 00 and some don't.
This is probably a bug (where an unsigned integer with its high bit set is not printed with a leading 00) and should be reported.
Note that RSA key moduli generated by OpenSSL will always have the high bit set, and so will always have 00 prepended when you ask it to print them. The same is not necessarily true of other integers.
This is trivial to demonstrate:
$ while true ; do openssl genrsa 1024 2>/dev/null | openssl rsa -text 2>/dev/null | grep -A1 modulus | tail -n1 | egrep -v '^\s*00:[89abcdef]' ; done
> I don't really buy this explanation. It's a very large unsigned number. Everyone knows this.Everyone knows that an RSA modulus is a very large unsigned number yes. Not everyone knows that every number is unsigned.
> Is there some arbitrary precision library in use that forces large integers to be signed?
OpenSSL's own BN (BigNum) library, which tests if the high bit is set in the input (line 482):
https://github.com/openssl/openssl/blob/a0d1af6574ae6a0e3872...
> Even if it were signed, or had the MSB set, it wouldn't change any of the bits, so the key would still be the same. So why would we care about the sign?
Because the encoding doesn't care about the context. RFC 3279 specifies that the modulus and exponent are encoded as INTEGERs:
https://datatracker.ietf.org/doc/html/rfc3279#section-2.3.1
... and INTEGERs are signed (which means OpenSSL has to use signedness == SIGNED):
https://learn.microsoft.com/en-us/windows/win32/seccertenrol...
Integer values are encoded into a TLV triplet that begins with a Tag
value of 0x02. The Value field of the TLV triplet contains the encoded
integer if it is positive, or its two's complement if it is negative.
If the integer is positive but the high order bit is set to 1, a leading
0x00 is added to the content to indicate that the number is not negative.
See also the canonical specification (page 15, section 8.3): https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-...This is exactly the same way that signed integers are represented in e.g. x86 (minus the leading tag and length fields) -- if the leading bit is set, the number is negative.
You're right that it wouldn't change any of the key's bits, but it would change the math performed on them, in a manner that would break it.