Where Are The Keys to Your Digital Castle?

A breach of your trust infrastructure is one of the most costly (and embarrassing) cybersecurity threats, and where a single breach of an…

Where Are The Keys to Your Digital Castle?

A breach of your trust infrastructure is one of the most costly (and embarrassing) cybersecurity threats, and where a single breach of an encryption could call into question many elements of a security infrastructure. It basically happened with Solarwinds, where an intruder managed to acquire the private key used to sign for software and then inserted a backdoor into a new release.

Overall, a system is only as strong as the weakest link in the chain, and so in cybersecurity we often need to understand the elements that would allow our digital walls to come crashing down. One of these is the access to your private keys, and one of the most fundamental of elements of this is often your OpenSSH keys.

If you’re a developer, a security architect or a cloud engineer, you will probably know all about using your OpenSSH keys and how you can use them to log into remote sites for both SSH connections and for authentication. Many use it for GitHub and Cloud integration, and thus to avoid having to continually enter login details. And, so, if Bob (the client) wants to connect to Alice (the server), he will generate an OpenSSH key pair and then place the public key on the server, and where he can then log in with his private key:

Basically, when Bob logs in, he is able to sign a message with his private key, and where Alice can prove this with the provided public key.

What do the keys look like?

The main key types used, these days, are RSA (typically 2K or 4K keys), ECDSA and Ed25519. A typical command to generate the key pair is [here]:

$ ssh-keygen -t rsa -b 4096 -C "[email protected]"

and which will generate a 4,096-bit RSA key pair. We typically store the private key in the ./ssh folder, and which contains a public key in the form:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAXQMfdioW/ibO3rtEACYqplJjfYa2hSqQtfNIk4h
7Dah+IrHeiN0m8vr2ldkso2gqQpvxFArJZ2EAiRtMQVfeTyauhd5rk0x8H00AfQABJDq6grldiz
uYy5tCC7V2Fw==

It is this key that we load onto the server we wish to connect to. The private key typically has a PEM form:

-----BEGIN PRIVATE KEY-----
MIIB1QIBADANBgkqhkiG9w0BAQEFAASCAb8wggG7AgEAAl0DH3YqFv4mzt67RAAm
KqZSY32GtoUqkLXzSJOIew2ofiKx3ojdJvL69pXZLKNoKkKb8RQKyWdhAIkbTEFX
3k8mroXea5NMfB9NAH0AASQ6uoK5XYs7mMubQgu1dhcCAwEAAQJdAjrb+LAUaQe8
+cFTze0UeK48Ow5nxn4wvniriIA9v3vaMGJ0Hl6qkFO1qq76O+uvSehxPHnzBrfs
SXkQ8nScyeGpoTpn0DCnMnFRiY1hAMy6SqVdC4t7UP9u6oCBAi8B+POU6nCyUOnL
FlPVGFoBxSoxC7q7tJytq+xaPfGBN63AT3sdnXm06YAH1uE/1wIvAZVPf+1sDjIP
c4hFNPzIPh/x1M3qDN9eBr6tdPwymuPmpQ1lik/b9ZpMfXGns8ECLwDTVfcci+BF
tyP1i06jq4AUKg1u8E+BTxXs37YBOOOxDvpvCYMiln6eP6SITavvAi8A6n71d8rl
p6by4+uOjZXZA6hpw7zfN7hx1I4MugEZRjPiWI7f5/ZN8bjBdylcwQIvAQp1f9vQ
S+P5ktRlO7vEm10LtKotJ85Rp+le7PX56re+nntKVZFsliKW0yPmWJE=
-----END PRIVATE KEY-----

If this key was to be discovered, an intruder could access trusted areas. So, notice, we have “ — — — BEGIN PRIVATE KEY — — -” banner on the private key. So, on Linux and Mac OSX, how do we scan our system for these private keys. One method is proposed by CraigHRowland [here] as:

find / -maxdepth 5 -name .ssh -exec grep -rnw {} -e 'PRIVATE' \; 2> /dev/null

In a scan of my system is quickly finds the following keys:

~ % find / -maxdepth 5 -name .ssh -exec grep -rnw {} -e 'PRIVATE' \; 2> /dev/null
/Users/fred/.ssh/id_ecdsa:1:-----BEGIN OPENSSH PRIVATE KEY-----
/Users/fred/.ssh/id_ecdsa:9:-----END OPENSSH PRIVATE KEY-----
/Users/fred/.ssh/id_rsa:1:-----BEGIN OPENSSH PRIVATE KEY-----
/Users/fred/.ssh/id_rsa:27:-----END OPENSSH PRIVATE KEY-----

In this case, we just look for the .ssh folder, and then do a grep to determine if it contains the word of “PRIVATE”. It can thus be seen in the test run that I have a number of OpenSSH private keys. On your system you should not delete any of these, unless you know what you are doing, but should certainly know where they are (and set some restrictions on them).

ECC Keys

The most popular set of OpenSSH keys is with RSA, but we can also use ECDSA, Ed25519 and DSA keys:

ssh-keygen  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]

In the following, we can create our ECDSA private key and then produce the OpenSSH public key [here]:

import sys
from Crypto.PublicKey import ECC
from Crypto.Util.number import *
from ecdsa import ECDH, NIST256p
import binascii
msg="hello"
test=1
curve_name='P-256'

if (len(sys.argv)>1):
test=int(sys.argv[1])
try:
M= bytes_to_long(msg.encode('utf-8'))
if (test==1):
d=0xE6CB5BDD80AA45AE9C95E8C15476679FFEC953C16851E711E743939589C64FC1
curve_name='P-256'
if (test==2):
d=0xE2563328DFABF68188606B91324281C1D58A4456431B09D510B35FECC9F307CA1822846FA2671371A9A81BAC0E35749D
curve_name='P-384'
if (test==3):
d=0x01D924DCCA0A887F8D99767A37D874E637A12CCB477D6E08665356694D68B7655E5069638FDE7B45C854013DC77A35B18655B84C966A60220D40F91ED9F5145802EA
curve_name='P-521'

key=ECC.construct(curve=curve_name,d=d)
print("=== ECC Private key ===")
print (f"d={hex(d)}\n")
print (f"Public Key (x) {hex(key.pointQ.x)}")
print (f"Public Key (y) {hex(key.pointQ.y)}")

print("\n=== Private Key PEM format ===")
eccKey = ECC.construct( curve=curve_name,d=d )
pubKeyPEM = eccKey.export_key(format='PEM')
print(pubKeyPEM)
print("\n=== Private Key DER format ===")
pubKeyDER = eccKey.export_key(format='DER')
print(binascii.hexlify(pubKeyDER).decode())

pub= eccKey.public_key()
print("\n=== Public Key PEM format ===")
pubKeyPEM = pub.export_key(format='PEM')
print(pubKeyPEM)
print("\n=== Public Key DER format ===")
pubKeyDER = pub.export_key(format='DER')
print(binascii.hexlify(pubKeyDER).decode())
print("\n=== Public Key OpenSSH format ===")
pubKeyOpen = pub.export_key(format='OpenSSH')
print(pubKeyOpen)

except Exception as e:
print(e)

A sample run for the P256 curve for a SHA256 hash is:

=== ECC Private key ===
d=0xe6cb5bdd80aa45ae9c95e8c15476679ffec953c16851e711e743939589c64fc1

Public Key (x) 0x422548f88fb782ffb5eca3744452c72a1e558fbd6f73be5e48e93232cc45c5b1
Public Key (y) 0x6c4cd10c4cb8d5b8a17139e94882c8992572993425f41419ab7e90a42a494272

=== Private Key PEM format ===
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg5stb3YCqRa6clejB
VHZnn/7JU8FoUecR50OTlYnGT8GhRANCAARCJUj4j7eC/7Xso3REUscqHlWPvW9z
vl5I6TIyzEXFsWxM0QxMuNW4oXE56UiCyJklcpk0JfQUGat+kKQqSUJy
-----END PRIVATE KEY-----

=== Private Key DER format ===
308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420e6cb5bdd80aa45ae9c95e8c15476679ffec953c16851e711e743939589c64fc1a14403420004422548f88fb782ffb5eca3744452c72a1e558fbd6f73be5e48e93232cc45c5b16c4cd10c4cb8d5b8a17139e94882c8992572993425f41419ab7e90a42a494272

=== Public Key PEM format ===
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQiVI+I+3gv+17KN0RFLHKh5Vj71v
c75eSOkyMsxFxbFsTNEMTLjVuKFxOelIgsiZJXKZNCX0FBmrfpCkKklCcg==
-----END PUBLIC KEY-----

=== Public Key DER format ===
3059301306072a8648ce3d020106082a8648ce3d03010703420004422548f88fb782ffb5eca3744452c72a1e558fbd6f73be5e48e93232cc45c5b16c4cd10c4cb8d5b8a17139e94882c8992572993425f41419ab7e90a42a494272

=== Public Key OpenSSH format ===
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEIlSPiPt4L/teyjdERSxyoeVY+9b3O+XkjpMjLMRcWxbEzRDEy41bihcTnpSILImSVymTQl9BQZq36QpCpJQnI=

We can see we can display the private key in a DER or PEM format, but can display the public key with DER, PEM or OpenSSH. In this case the private key is:

-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg5stb3YCqRa6clejB
VHZnn/7JU8FoUecR50OTlYnGT8GhRANCAARCJUj4j7eC/7Xso3REUscqHlWPvW9z
vl5I6TIyzEXFsWxM0QxMuNW4oXE56UiCyJklcpk0JfQUGat+kKQqSUJy
-----END PRIVATE KEY-----

and the public key is:

=== Public Key OpenSSH format ===
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEIl
SPiPt4L/teyjdERSxyoeVY+9b3O+XkjpMjLMRcWxbEzRDEy41bihcTnpSILImSVymTQl9BQZq36Q
pCpJQnI=

DSA keys are hardly used these days and are generally deprecated from the Internet. Overall, compared with ECC keys, they are rather long [here]:

=== Public Key OpenSSH format ===
ssh-dss AAAAB3NzaC1kc3MAAAEAAy3VU30zepE0N9Neo0M9sOe3ISmPuocn8vm+hW1qFGuSmI1Qg
vLFcrdwN2PoJFSnpKIlmyms6bC8m0tNmF1qnIy2MOTgn0gHnxvoB2lx3pJoVnC5TMlofdwjOzCvIp
SwMKa0l/ZG+U4cF+g6kEwsG2hEEM4Ej9nNZAWhSqaMK49/i9Bun2TEu2nMv7yAVq5BSosuNdYgXN7
7KiSjebihFhdQlf9X/2FVEoaG2ZuOHyREYxJx8JwzTzciRS/pJj/DNJ5vMwemdU/9idRDJzh9/UAY
oCrqbvTGNqdp5863NxkZckmoQaML4MS+jssQfzgC3EWD+OASlNUrYhNnvQwZUwAAAB0BlQmy7ag7C
IJzGz/onC72nbjYNhI0XRpmpYO5EQAAAQAArF0SDkbSutaHiEfM6HCmntytyGyFnEm6963kHtk2js
I7ZFT7YOrarMZkKm/dMiuZqxR1gbIb6+BilOOCC8VW+lQRsxw3OzmmfVGKVHcTQVxnrO8YvGupTJV
gDLW9qDyErVjlSR0mJh7U5TWtsi41sGzCtMidotxj4p7aBvATgHJGVYky6fLci5Mua4S0B/VxUJ0G
95Qw6V1GstAmFCiEF5mYhqZxRe10agyowERBA/UD5rvnRWHDrNGa5XqCZ6G8PEkwg7sWxZeorJmB+
3BFhxf7ZJykYdRwtLNePphk+hpZm8Aeb+mTClH1ebCEAXQluNChAj+u3dxX0c5WJRzaAAABAAIwN
7LZyZ51P9J5v/ze6ZKcm6HeqpcLA3KvczXlUCE3QpnzYQJ8jWXVevtNPM0rRyS1Pwnr4oy/SZ9rT4
YzSRmLJLKrDUzstsT9fmctSyrKnTnjriD47Nf9dxB85Upm3e6XROSM+N1rqaUox1HwCMZvGSogTsf
5OHaRAXmxMR2XW0klxWmQKfvRFKXnkBkKTTiblI+PV2qORaVr4NT9bOpjHF9TfvkYWY4wUi+TZFB
mGMBFhMpv0HUSEiGkYPmAxU+AHX1tIZ3yodvqPIoDoJ9r6Ru2KW15GiqDgOidDN0m92Y+BpqDMUm
tRCssE5iHcfZUuB9Q4NcmQkfWeOrrsPk=

Conclusions

Your private keys can be the keys to your castle … so look after them. If you want to learn more about OpenSSH key generation, try here:

https://asecuritysite.com/openssh