Let’s say you have a string that contains both a private SSH key, and the public key, both in PEM format. How do you separate them from each other?
const content =
"Private Key:-----BEGIN OPENSSH PRIVATE KEY-----
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
YourPrivateSSHKeyYourPrivateSSHKeyYourPrivateSSHKey
-----END OPENSSH PRIVATE KEY-----
Public Key:-----BEGIN PUBLIC KEY-----
YourPublicSSHKeyYourPublicSSHKeyYourPublicSSHKey
YourPublicSSHKeyYourPublicSSHKeyYourPublicSSHKey
YourPublicSSHKeyYourPublicSSHKeyYourPublicSSHKey
YourPublicSSHKeyYourPublicSSHKeyYourPublicSSHKey
YourPublicSSHKeyYourPublicSSHKeyYourPublicSSHKey
-----END PUBLIC KEY-----"One way is to use a regular expression which specifically targets their format. Private keys are almost always contained within a header and footer.
const privateSSHKey =
/-----BEGIN(.+)PRIVATE KEY(.+)(\n.+)*END(.+)PRIVATE KEY-----/.exec(content);
const publicSSHKey =
/-----BEGIN(.+)PUBLIC KEY(.+)(\n.+)*END(.+)PUBLIC KEY-----/.exec(content);This can be cleaned up a bit:
const privateSSHKey =
/-{5}BEGIN(.+)PRIVATE KEY(.+)(\n.+)*END(.+)PRIVATE KEY-{5}/.exec(content);
const publicSSHKey =
/-{5}BEGIN(.+)PUBLIC KEY(.+)(\n.+)*END(.+)PUBLIC KEY-{5}/.exec(content);-{5}exactly 5 instances of-BEGINexact match(.+)- something could be here, if anything.matches any character (except for line terminators)+matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
PRIVATE KEYexact match(\n.+)**matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)\nmatches a line-feed (newline) character (ASCII 10).matches any character (except for line terminators)+matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
ENDexact match(.+)- something could be here, if anythingPRIVATE KEYexact match-{5}exactly 5 instances of-.exec()executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.
Depending on the format the header and footer may have a varied string:
------BEGIN OPENSSH PRIVATE KEY------
------END OPENSSH PRIVATE KEY------------BEGIN RSA PRIVATE KEY------
------END RSA PRIVATE KEY------------BEGIN PRIVATE KEY------
------END PRIVATE KEY------------BEGIN OPENSSH PUBLIC KEY------
------END OPENSSH PUBLIC KEY------------BEGIN RSA PUBLIC KEY------
------END RSA PUBLIC KEY------------BEGIN PUBLIC KEY------
------END PUBLIC KEY------This is why we need to include (.+) between BEGIN and PRIVATE KEY .
What if the public key was in the ssh-rsa format?
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC7jdirkf4o6 ...You could do:
/ssh-rsa(.+)==/;The values can then be assigned to a key/value pair within an object, for example:
{
privateKey: privateSSHKey,
publicKey: publicSSHKey
}Resources:
https://www.thedigitalcatonline.com/blog/2018/04/25/rsa-keys/