0

I saved an rsa private key in a binary file (in PEM format), among other data. I knew its offset, but not its size. When I needed to load, I generated a temporary key, and used its size to load the saved one (I do not want to process text to extract the key).

I was a bit surprised, because for a modulus of 2048 I got two encoded key sizes: 1679 and 1675:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvsAqMhhCurk2ROslaeNDf5K4oedJiyqxAeIWhgWfYeLqxDQ7
U7A+r/HEoUjUQMia6dBLXVI+FyF0PhNJwIBAtlGu/ojSEppSA4los9u5Q4SNrpwZ
dSgIPIRWa1HSBoL464K9hIY5iXxku3jGeWgIHlKtaVeoSxhYv4lwAYL0QAKs24Bc
VC1JaLDVMldwf3CBqKiyoXhLIPGpW5PMPLKR0Tj44+4gm7vgQ/wOaavYp6DW2kaH
EZyu7T4viqpAdUk5dHi6HHTOzarhDP+1B8aL7scqZzTtzjbidyXVbm5vBjTSQqO5
865k9+p9znhVA5tS7Ha+zAKiGhRjXtRkRLxKdwIDAQABAoIBAA9h5cU2aaMvLm4u
XE0Gs7nE9jiwMyES50VUmyZhq7G0H+SEpcgg7V047PdorR0wUDXMw1caO8GXxA0B
dzAb55wMSEVkeTRg135LhXMDpBQKy3YqRm9JNCjVLzbmWT6HL1WmrGvUey1YJ7Nq
kO7XcdgoKK3XEM5Ff1qq1ap5igLjUGn3Ibna4faaVFvbw00/WYHqPUejmEn+xYV8
I8KrplZ2+0iE7nxrRQwdZWtyRgmjF81rJJPKw0BDiESXADkjdil9FPwMgCqJ8shZ
JhlslsYkD6JC/fS0u5w2h72dZY1chPqLex4CSUr3X3jGvUNkQt+l8jPs9p1zT7hP
jwPA6JECgYEA+s5Iz+rs5Y136VofAPSiGwrBuM1tvjpkV+tbUhlxJxem6JXypEYx
YFZ2fqwn9Timxfgsihjun1R1yn5wFjsylAB5lWgyNgt2uvTJrwsC3KpdEESGWlE/
c2yS7UJwWiZ3YcRP8tEwZre9VREdo7pObb+h3ZytoHMUNau18dJ5FBkCgYEAwrN7
R/euWvfutvCtHhE9xiAqu4qph9WYbx541zK8c5Vra+1JqnrBBPiXv6dxHnwlWV8g
CxH/PhjRSB+vyKn/bfHH5mfAYeAVwxIo04jdcc+vPETySITs9KN9KPnmYwSM1rJU
Fbo7X/0B+pHxVfj2kGlKyY2Jro84gToOckkwpQ8CgYEAqN/9ZwJoQKjg9N8ZwSr3
e/3iMu0f19a5efmfo8g9yHTEjhdpKfOZi6SsZN7GiPd8VBCm7NWc1uun5JD+J/n0
NHOdalyecoWFjJ0GsDZZ1vtfbnS1glryvmV9CQSTYiBEgjANJRJ15LQTaBP+QSBR
btR5yR6WSlMyaHEWMZ3mqQECgYEAk9kDFqVIKx/2j8i3TQu+owKuMHedQN67wDWd
gZyvaf3e8rffpqtMg1/aq9iUl5eiLPmFNaLW9eqWkXQuYexlYLGnIJlMh4ZIQDc7
9VYLAm+5G8UnTlZSMXssgb8yaaJ86FPGcjFXAQ75P7MvVh+V7BdoiSEHmhx7xfW2
HqbhX5UCgYA7UmzmedDd74yfzTbKv7xiTiTL5uQcra51iVFUNU+7Xv2ou11674ak
ymSyEfbLyNq0fZZSj538OVYLK7WG6YEED3nQ5bGvh8MfDHUcI2WgMzZloKUY7UWF
G0/AjGI55sEu+/nu9yPvhNEbq7nfa6LhBkLpB+RAgMhZ6dskdP4Eng==
-----END RSA PRIVATE KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEApBxAjMLR4FOHPvgL2JiFoefQiArset5UTUV1VH+bes1saO4C
O0WZVXr8Ksj+Cnw4Secd8evy2frhEI3DCWizLn8/SVySmIX442H6nbgo0PokCEYo
a4ghI5dbc0QLXuyLL7VMRjwOVhpsd51Tx1pAJx0aHlQvmr2a3xaICI8F4hhTtI0r
IEoiaqWocJs9BjZd9gNqDK47UD9svjzLKc0jJ/yRCDsUGIvhYcYIzir6+NQTCU8Z
kvlmgO3WT8U3OdbnhhtuomjSjc/1TBOqbtRXLpQ+yLOJm6Op7XZb2h2iCuH9Hp9/
oy3DmpdXOYqtLYFUVyE26PwEPG5alw4QQbahJQIDAQABAoIBAQCA5JOqOqV+a/xQ
b59WOczTMe/tua6sfgx2ODSD7kmedNNNwonMJcjdg1+k9wHYGGJZYQV66ddubwXv
63eg3zPENDrvkp6s3qRxapXc5DRileRQ/1Fly6BDhPBVor7PijdzfBBxJWAZLl28
wLt5WqACWHAYHATbo0mNJ/QlzLdRMIoWFaJK71pn1pka1DZxzfk//uV+L6NCMAbP
e+PAArY/8bTQYOnlKHoPrjpmyDYtliOYDCr3OgZqS7dS69cz5jHNihHLJiKfOTNr
zyXFBAfPwWUqBsUagj5GCb3yeyalfY2y/9DBPvfY75+e6KtZcMtDXRzqV/hWswk5
ApWfqfqtAoGBANHdn4/AKTH4AIP+nNx2HTFsin7KnwjNbMFWbxrC/JjQqX90ugie
y1LzWiWgCXMo0tOuKsd6AWQEQQBAbxhCAjRZ6XfLVllmMXYVZQ2wwxNYwB49Vi9p
ZNsvGBKpcUbgzFkm2pRc8GkvjDz1iJxnKnVY0ATpjuK6CMhsDYkeyhXjAoGBAMgv
tMh1EFYJA2ewieCD+xlcAk8YZVc8b9JV2cdHtpAHCvMMbPm4S/ygwvZ1FadvVrX8
z6CRMVsRbmp4a5dDUkRQqAm5LUqZ59e2MHoYq5ueR145MXDZXhT5BoTZ1LC+r6nN
0Low1xP78sjTxSOb2aUvlSWG54y7+lVJkKf9cNtXAoGAPE4C27vMGp+5BjTTvkXy
fZFC+swehtkAt02u/3GoRAExs35HNtLqehuTe9xQ2taQPmN9x3Q3khXm17usMLxH
BeQQQmwbk/TZoaTkNNrmM1j9W7MkYNtYL+OId1RZSJSwI64WgStzqcYP9jRX3RmI
CdBLdh3nAR+UBoOGIDDIwSECgYAaBlmyVcWx6aoPqNvD3GSgf12terZyCOFgrtiJ
F8GcJ848mrjwHg2C4kN2VvJhug/DyQIVFcsc079PCCi0mYPwbavq17ATqr6BRKY4
uUxWBtWwYi8TRK7+ewFl9Au6jo+3u5IPIppTdsWxZhaS8ofw+aaiIk+n9CgvPkkY
DdLGMQKBgCQyM7Mg8xCgVQaQWAFJ8jHSrZfsk2+Xrj7oDW0JGa3Es3kXrWH/h/9/
VIP8/H1kzyuqDwuPN/1BzKfpIxzz2TGrK+KUAJsIN4j+Kh0yQDV/Pxw9sGx71Aid
m3AQwxAk8a10B1jbj/qPvxZjZZxqoILC4xIkWYrabFku2zot5yUx
-----END RSA PRIVATE KEY-----

Can I save an rsa key in a format, which always has the same size if the modulus is fixed?

The public key appears to always have a size of 451. Can I assume that this is constant?

  • What exactly do you mean by size here? You seem to be talking about the bytesize of the PEM-formatted private key file, and not the actual length of the key. – Jedi Jun 28 '17 at 15:58
  • (1) In a binary file you could store the 'DER' (binary) encoding; that also varies in length, but it is self-delimiting so when using OpenSSL you only need to give d2i_* an upper bound not the precise length. (2) A 2048-bit RSA public key with OpenSSL's default e=65537 in OpenSSL's normal 'pubkey' form (i.e. X.509 SPKI) is consistently 294 octets in DER or 451 or 460 chars in PEM depending on whether you use Unix newline or Win/DOS CRLF. – dave_thompson_085 Dec 5 '17 at 2:20
1

If you look at the keys in an online tool like: https://lapo.it/asn1js/ , you'll find the RSA private key consists of 9 different fields, some of which are variably sized.

In particular, if you look at the key file format here: https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem (PKCS#1) you'll see the definitions for the 9 fields.

First key is:

SEQUENCE (9 elem)
INTEGER 0                     -- version
INTEGER (2048 bit) 24080037…  -- modulus
INTEGER 65537                 -- e
INTEGER (2044 bit) 19418496…  -- d
INTEGER (1024 bit) 17612182…  -- p
INTEGER (1024 bit) 13672376…  -- q
INTEGER (1024 bit) 11858803…  -- d mod (p-1)
INTEGER (1024 bit) 10382218…  -- d mod (q-1)
INTEGER (1022 bit) 41657306…  -- (inverse of q) mod p

And the second key is:

SEQUENCE (9 elem)
INTEGER 0                     -- version
INTEGER (2048 bit) 20717013…  -- modulus
INTEGER 65537                 -- e
INTEGER (2048 bit) 16271218…  -- d
INTEGER (1024 bit) 14737271…  -- p
INTEGER (1024 bit) 14057563…  -- q
INTEGER (1022 bit) 42347422…  -- d mod (p-1)
INTEGER (1021 bit) 18275240…  -- d mod (q-1)
INTEGER (1022 bit) 25417766…  -- (inverse of q) mod p

So, as you can see, some of the components of the key are different sizes (upto 4 bits on the d field), and those will be encoded somewhat differently in the ASN1 and base64 format.

As to your questions:

I don't know of a way to generate exact size RSA key components; if you can I would just prefix the length of the string in the file format. Or alternatively search the file for the '----' bit. You may be able to generate the ASN file with additional leading 0's on fields to get everything to a fixed length. Or you could generate RSA keys until you get the size you want. /s

Public key, so long as you're using the default e=65537 (default everywhere, for everyone), it's probably safe to say size==451. Though I'd still length prefix any plain text in a binary file.

  • 1
    X.690 BER (and DER) requires that integer encodings be minimal length; I expect at least some decoders don't check, but I wouldn't count on all. Looking at the source it appears OpenSSL historically didn't but 1.1.0 (released 2016) does. PS: given OpenSSL as tagged in the Q, you can also see the fields with commandline openssl asn1parse <pemfile or ... -inform der <derfile – dave_thompson_085 Dec 5 '17 at 2:22

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.