Bare Metal RSA

I love detail. As a child, I would spend a great detail of time taking the back of things, and trying to understand how they work. So in…

Photo by michael schaffler on Unsplash

Bare Metal RSA

I love detail. As a child, I would spend a great detail of time taking the back of things, in order to understand how things actually work. So in Cybersecurity, I love probing around and investigating the core formats. In fact, I think it is one of the most important skills. So, I’ve been investigating the DER format for storing cryptography asset, including for storing keys and digital certificates. If you want to understand the DER format, please read this:

Now we generate an RSA key with:

openssl genrsa -out private.pem 1024

This produces a PEM file:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCjmcr22TtipralMR7+k8TWRzl8oFqY+lzdty1oFqsW/IX5QO/p
zyIzl1yJJcYPTNNWdnzIRFaGMToMrq4ykwBwypBZGhsknC/O+SgPWhHY8ZkFedhq
BbJSP1LEqHbaLWNcon+/8ZXm9wFfg0ko8DOiCyzQIWqFKViz5Y0Pm9VCMwIDAQAB
AoGAP9QD1NUiDzYd8ks83XQHitZU/mONlTuwuav64i5d5+Tz3DBSqfTvUhOOvc9n
+5YsqgImYvgOjeJs1H/eZMrnk3n2uz7tuqiGM13FgmEPtK5X7BMxZN5Lc19jUQ3p
vJwRx9VP62GRm0ZxO0NczApxQ1aJhc34Zxi7hMIKyOZuqIkCQQDYJvvNTzNoJpKH
O7Vbw5TD0TEv7LCpuHXWqzqqadMvoKy48qvDWjXJ/pWYRVSVmi5pfUOp6nEqtpWs
rLPkaHuPAkEAwcK15pK3j5kud+bX5m+b+YLhrw7/BElhbnbvjZY33MRCkag5inwp
ZqK3IRwf+Ru7TOT64CUbdlyy93jF/jcNHQJBAJxmOLQppoypvERVk7g+IBo/91Mx
8/IaIkmdw+kigUho/hEkpdvIHjt2FlADelx1Hzf9B0Se+htp2YsDu3Z9k0kCQEL/
VbBtiOUxXVz+SCcY7oDfHbRPZiSQTw1IONrnV1eR0UbWOVdGSXaAyvu64t9bFG+p
OYopqo5JzWQ+sY+Ob40CQQCJJ+z2iKD3mLRMfUP9tQcSnmNuJFQTY1oav34uiEGe
DtfscVwkjZNSOrzCF9fTfiXEeMmPyOh+WfJA9fw2GLoh
-----END RSA PRIVATE KEY-----

We can convert this into a DER format with:

openssl rsa -in private.pem -outform DER  -out private.der

and we can then convert this into a hex string with:

> xxd -plain private.der | tr -d '\n'
30819f300d06092a864886f70d010101050003818d0030818902818100a399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd542330203010001

A public key is then created with:

openssl rsa -in private.pem -outform DER  -out pub.der -pubout

Using the program here, we can produce a sample run for an RSA public key from the DER file:

==Sequence==
--->Sequence (30)
--->Obj ID tag (06 - Object ID)
ID algorithm: 1.2.840.113549.1.1.1 RSA Encryption
--->Obj ID tag (03)
--->Obj ID tag (02 - Integer)
0xa399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd54233
--->Obj ID tag (02 - Integer)
0x10001
Now checking key if RSA
 Public RSA key at 0x7F858855EE80
 -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjmcr22TtipralMR7+k8TWRzl8
oFqY+lzdty1oFqsW/IX5QO/pzyIzl1yJJcYPTNNWdnzIRFaGMToMrq4ykwBwypBZ
GhsknC/O+SgPWhHY8ZkFedhqBbJSP1LEqHbaLWNcon+/8ZXm9wFfg0ko8DOiCyzQ
IWqFKViz5Y0Pm9VCMwIDAQAB
-----END PUBLIC KEY-----

This gives N (modulus) and e (public exponent). The value of the modulus is 0xa399caf6d9…33, and e is 0x10001. To encrypt we just take a message (M), and create a cipher (C) of:

C = M^e (mod N)

A sample run for an RSA private key is [here]:

DER string: 3082013a020100024100a53c172810b45f94cb1edbd6a7eeffd5fa94b4c692d00bec0760bc53dff8b3034ed82f92debb553ae6fc0663ab90247e71af25a7643ad055cec78345b92c36c7020301000102403de24885efe3ae1c8b0a6ea97151d8ad6a610167919aabac6582fc65a96f7a937b40f06c5594f0fe1a74b957e731a021f9b214bfcb7fecfee328a9b041eb8d41022100da6a12118066136f8b1478dd78625bb80ed2ffa6b525a0cbc89058a37040faa7022100c1ab44c7fd1fcc554f4143072361f0bf064619b25fcc54064def8692da5006e102203bf114585d46a65adc6e97e5201ece512b30591d2565d845551bd857b27d02cd02201acc03dc581dca3c1397481af8be587d55f4e521553804784ad8559a84328681022100bd24bc374ab656a11b2d531ac4eaebb5dd013848c654268d453942a39248bc32

==Sequence==
Integer (02): 0x0
Integer (02): 0xa53c172810b45f94cb1edbd6a7eeffd5fa94b4c692d00bec0760bc53dff8b3034ed82f92debb553ae6fc0663ab90247e71af25a7643ad055cec78345b92c36c7
Integer (02): 0x10001
Integer (02): 0x3de24885efe3ae1c8b0a6ea97151d8ad6a610167919aabac6582fc65a96f7a937b40f06c5594f0fe1a74b957e731a021f9b214bfcb7fecfee328a9b041eb8d41
Integer (02): 0xda6a12118066136f8b1478dd78625bb80ed2ffa6b525a0cbc89058a37040faa7
Integer (02): 0xc1ab44c7fd1fcc554f4143072361f0bf064619b25fcc54064def8692da5006e1
Integer (02): 0x3bf114585d46a65adc6e97e5201ece512b30591d2565d845551bd857b27d02cd
Integer (02): 0x1acc03dc581dca3c1397481af8be587d55f4e521553804784ad8559a84328681
Integer (02): 0xbd24bc374ab656a11b2d531ac4eaebb5dd013848c654268d453942a39248bc32

This gives version, N (modulus), e (public exponent), d (private exponent), p1 (prime 1), p2 (prime 2), ex1 (d mod (p-1)), ex2 ( d mod (q-1)), co (co-efficient). We can see that N is the modulus, d is the private exponent. If we have a cipher, we can decrypt with:

M = C^d (mod N)

and that’s it. Notice that the private key also has the two prime numbers used, and which create N and where:

N = pq