Embedding key as string in Paramiko application
Question:
I’m trying to create a single file executable in Python and using Paramiko for my SSH. I need to eliminate external files such as private key files and try to go for embedded strings.
I tried this solution but it’s not working for me:
Paramiko: Creating a PKey from a public key string
How do I accomplish this? Thanks.
Answers:
The solution you mentioned:
key = paramiko.RSAKey(data=base64.b64decode('AAblablabla...'))
works fine however it may be inconvenient to store the key in base64 format.
The following code shows how to use the key stored in "plain-text" format (as key-files in ~/.ssh
directory):
import paramiko
import StringIO
my_key = """
-----BEGIN RSA PRIVATE KEY-----
<your key here>
-----END RSA PRIVATE KEY-----"""
pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(my_key))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='host', username='user', pkey=pkey)
...
ssh.close()
In Python 3:
import io
# ...
pkey = paramiko.RSAKey.from_private_key(io.StringIO(my_key))
To add a public key from a string on the ssh client you must set the keyword arg look_for_keys=False then use the MissingHostKeyPolicy classes missing_host_key() method to add the key from your string.
my_pub_key = "xx.xx.xx.xx ecdsa-sha2-nistp256 mlzdHAyNT....."
my_host = my_pub_key.split(' ')[0]
password = 'myFavortitePassword'
username = 'myUsername'
ssh_client=paramiko.SSHClient()
host_key_policy = paramiko.MissingHostKeyPolicy()
host_key_policy.missing_host_key(ssh_client, my_host, my_pub_key)
ssh_client.connect(hostname= my_host
,username=username
,password=password
,port=22
,look_for_keys=False)
I had the same issue where I’m trying to not have private key files using AWS secrets manager, just got it to work with the following. Notice the n
in the privatekey.
import io
privatekey = io.StringIO('-----BEGIN OPENSSH PRIVATE KEY-----nRestOfTheKeyn-----END OPENSSH PRIVATE KEY-----')
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
Then when you’re connecting
aws_ssh = paramiko.SSHClient()
aws_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
aws_ssh.connect(hostname='YOURHOST', username='YOURUSERNAME', pkey=pkey)
Now, however, if you’re like me and using this for Lambda+Secrets Manager, and the secrets manager has a key+value and you’re pulling the value of this privatekey from there. One thing to note is that secrets manager will escape the n
and turn it into \n
. To fix that, modify the above code to replace the \n
to n
.
awskeytemp = secrets['YOURKEY'].replace('\n', 'n')
privatekey = io.StringIO(awskeytemp)
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
I’m trying to create a single file executable in Python and using Paramiko for my SSH. I need to eliminate external files such as private key files and try to go for embedded strings.
I tried this solution but it’s not working for me:
Paramiko: Creating a PKey from a public key string
How do I accomplish this? Thanks.
The solution you mentioned:
key = paramiko.RSAKey(data=base64.b64decode('AAblablabla...'))
works fine however it may be inconvenient to store the key in base64 format.
The following code shows how to use the key stored in "plain-text" format (as key-files in ~/.ssh
directory):
import paramiko
import StringIO
my_key = """
-----BEGIN RSA PRIVATE KEY-----
<your key here>
-----END RSA PRIVATE KEY-----"""
pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(my_key))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='host', username='user', pkey=pkey)
...
ssh.close()
In Python 3:
import io
# ...
pkey = paramiko.RSAKey.from_private_key(io.StringIO(my_key))
To add a public key from a string on the ssh client you must set the keyword arg look_for_keys=False then use the MissingHostKeyPolicy classes missing_host_key() method to add the key from your string.
my_pub_key = "xx.xx.xx.xx ecdsa-sha2-nistp256 mlzdHAyNT....."
my_host = my_pub_key.split(' ')[0]
password = 'myFavortitePassword'
username = 'myUsername'
ssh_client=paramiko.SSHClient()
host_key_policy = paramiko.MissingHostKeyPolicy()
host_key_policy.missing_host_key(ssh_client, my_host, my_pub_key)
ssh_client.connect(hostname= my_host
,username=username
,password=password
,port=22
,look_for_keys=False)
I had the same issue where I’m trying to not have private key files using AWS secrets manager, just got it to work with the following. Notice the n
in the privatekey.
import io
privatekey = io.StringIO('-----BEGIN OPENSSH PRIVATE KEY-----nRestOfTheKeyn-----END OPENSSH PRIVATE KEY-----')
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
Then when you’re connecting
aws_ssh = paramiko.SSHClient()
aws_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
aws_ssh.connect(hostname='YOURHOST', username='YOURUSERNAME', pkey=pkey)
Now, however, if you’re like me and using this for Lambda+Secrets Manager, and the secrets manager has a key+value and you’re pulling the value of this privatekey from there. One thing to note is that secrets manager will escape the n
and turn it into \n
. To fix that, modify the above code to replace the \n
to n
.
awskeytemp = secrets['YOURKEY'].replace('\n', 'n')
privatekey = io.StringIO(awskeytemp)
pkey = paramiko.Ed25519Key.from_private_key(privatekey)