11

openssl x509 (v1.0.1f) displays public key moduli as arrays of hex-encoded bytes, 15 columns wide, starting with a leading 00::

    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (1024 bit)
            Modulus:
                00:b0:d0:f4:33:a8:b2:93:06:65:27:72:94:57:92:
                bd:c7:ca:d4:08:e7:06:b9:4e:5e:d4:4a:ff:cc:f3:
                4f:4a:fc:92:75:46:4f:ce:fc:18:4a:d1:30:f2:64:
                31:94:4d:13:0d:91:ef:a4:34:59:71:b4:a1:cd:4e:
                fe:8f:e4:57:71:55:6a:d5:47:db:12:db:aa:df:20:
                6a:36:d1:5d:8c:68:db:ef:63:87:56:df:79:71:50:
                69:8d:b8:67:32:e7:51:17:26:21:fd:20:c7:1d:d2:
                dc:78:d7:fe:98:42:d0:24:8c:6a:df:12:cd:da:a9:
                81:fb:60:8b:ba:c9:12:d3:a9
            Exponent: 65537 (0x10001)

GnuTLS's certtool -i shows the bytes in an array of 16 columns, which seems less surprising, but again starting with a leading 00::

Subject Public Key Algorithm: RSA
Certificate Security Level: Weak
    Modulus (bits 1024):
        00:b0:d0:f4:33:a8:b2:93:06:65:27:72:94:57:92:bd
        c7:ca:d4:08:e7:06:b9:4e:5e:d4:4a:ff:cc:f3:4f:4a
        fc:92:75:46:4f:ce:fc:18:4a:d1:30:f2:64:31:94:4d
        13:0d:91:ef:a4:34:59:71:b4:a1:cd:4e:fe:8f:e4:57
        71:55:6a:d5:47:db:12:db:aa:df:20:6a:36:d1:5d:8c
        68:db:ef:63:87:56:df:79:71:50:69:8d:b8:67:32:e7
        51:17:26:21:fd:20:c7:1d:d2:dc:78:d7:fe:98:42:d0
        24:8c:6a:df:12:cd:da:a9:81:fb:60:8b:ba:c9:12:d3
        a9
    Exponent (bits 24):
        01:00:01

When it comes to private keys, however, both openssl rsa and certtool -i -k show all the private key components in arrays of bytes 15 columns wide. They both show leading 00: for some components of the private keys but not others.

This display format seems unusual because the quantities in question are generally sized in powers of 2 (e.g. 1024 bits == 2^10), but the binary data is shown in rows of 15 columns. The leading zeros are surprising as well.

So… is there a good reason for this unusual display format?

e-sushi
  • 17,891
  • 12
  • 83
  • 229
Dan Lenski
  • 335
  • 2
  • 10

1 Answers1

16

As for the leading zero, I believe the tools are just displaying what's in the ASN.1 as is; the BER/DER encoding rules will insist on a leading 00 byte in some cases.

Specifically, if you encode a positive integer, the msbit of the value stored must be 0 (if it is a 1, the encoded value is assumed to be negative); if the msbyte of the value you want to store has a 1 msbit, then you must prefix a 00 byte byte to the stored value; this 00 byte does not change the value (obviously), but it does make the msbit 0. In both case you have, the most significant nonzero byte has an msbit of 1; hence, they have a 00 prefix.

Now, you state that other components within the private key do not have a 00 prefix; I expect that, if you examine them, the first byte of those values will be somewhere in the 01-7f range, and so don't need a 00 prefix.

poncho
  • 147,019
  • 11
  • 229
  • 360
  • Thanks very much! I'm a bit chagrined to admit that I didn't realize that the DER and PEM formats were based on ASN.1. – Dan Lenski Feb 07 '17 at 06:31
  • 3
    Any N bit key with N divisible by 8 will have the MSB set, so the 00 prefix is also very likely. – Simon Richter Feb 07 '17 at 09:54
  • 2
    The funny thing is that on the other hand in XML-DSIGs CryptoBinary format leading zeros are forbidden (RFC 3275 4.0.1). Nevertheless I have seen some frameworks adding a zero to work around implementations that incorrectly handle this type as twos complement (think of javas BigInteger(KEY_BYTE_ARRAY)) – Drunix Feb 07 '17 at 12:22
  • 1
    @SimonRichter: to complete that thought, n is usually chosen to be exactly 1024/1536/2048/3072/4096 bits and p and q half that size and thus need the 'extra' sign octet, but d is effectively random in (1,n) and dp dq qinv effectively random in (1,p) or (1,q) so they have about 2/3 or 8/15 probability of not needing it. – dave_thompson_085 Feb 08 '17 at 05:39