Openssh Python



Welcome to pyOpenSSL’s documentation!¶ Release v20.0.1 (What’s new?pyOpenSSL is a rather thin wrapper around (a subset of) the OpenSSL library. With thin wrapper we mean that a lot of the object methods do nothing more than calling a corresponding function in the OpenSSL library. There are multiple options to use SSH in Python but Paramiko is the most popular one. Paramiko is an SSHv2 protocol library for Python. In this lesson, I’ll show you how to use Paramiko to connect to a Cisco IOS router, run a show command, and return the output to us. Python wrapper around OpenSSH client intended to execute commands on remote servers. NetAngels/openssh-wrapper. Perform commands over ssh with Python. Ask Question Asked 10 years, 8 months ago. Active 13 days ago. Viewed 510k times 159. I'm writing a script to automate some command line commands in Python. At the moment I'm doing calls thus: cmd = 'some unix command' retcode = subprocess.call(cmd,shell=True).

I’ve posted a followup to this article that discusses ssh-agent.

For reasons best left to another post, I wanted to convert an SSH public key into a PKCS#1 PEM-encoded public key. That is, I wanted to go from this:

To this:

If you have a recent version of OpenSSH (where recent means 5.6 or later), you can just do this:

Python

If you don’t have that, read on.

The OpenSSH public key format is fully documented RFC 4253. Briefly, an OpenSSH public key consists of three fields:

  • The key type
  • A chunk of PEM-encoded data
  • A comment

What, you may ask, is PEM encoding? Privacy Enhanced Mail (PEM) is a specific type of Base64 encoding…which is to say it is a way of representing binary data using only printable ASCII characters.

Openssh Python

For an ssh-rsa key, the PEM-encoded data is a series of (length, data) pairs. The length is encoded as four octets (in big-endian order). The values encoded are:

  1. algorithm name (one of (ssh-rsa, ssh-dsa)). This duplicates the key type in the first field of the public key.
  2. RSA exponent
  3. RSA modulus

For more information on how RSA works and what the exponent and modulus are used for, read the Wikipedia article on RSA.

We can read this in with the following Python code:

This leaves us with an array that, for an RSA key, will look like:

We need to convert the character buffers currently holding e (the exponent) and n (the modulus) into numeric types. There may be better ways to do this, but this works:

We now have the RSA public key. The next step is to produce the appropriate output format.

Our target format is a PEM-encoded PKCS#1 public key.

PKCS#1 is “the first of a family of standards called Public-Key Cryptography Standards (PKCS), published by RSA Laboratories.” (Wikipedia). You can identify a PKCS#1 PEM-encoded public key by the markers used to delimit the base64 encoded data:

This is different from an x.509 public key, which looks like this:

Openssh PythonOpenssh PythonOpenssh

The x.509 format may be used to store keys generated using algorithms other than RSA.

The data in a PKCS#1 key is encoded using DER, which is a set of rules for serializing ASN.1 data. For more information see:

  • The WikiPedia entry for Distinguished Encoding Rules

Basically, ASN.1 is a standard for describing abstract data types, and DER is a set of rules for transforming an ASN.1 data type into a series of octets.

According to the ASN module for PKCS#1, a PKCS#1 public key looks like this:

We can generate this from our key data using Python’s PyASN1 module:

Python Execute Shell Commands Remotely Over Ssh

Now that we have the DER encoded key, generating the output is easy:

Whereas the OpenSSH public key format is effectively “proprietary” (that is, the format is used only by OpenSSH), the private key is already stored as a PKCS#1 private key. This means that the private key can be manipulated using the OpenSSL command line tools.

Python Openssh Sftp

The clever folks among you may be wondering if, assuming we have the private key available, we could have skipped this whole exercise and simply extracted the public key in the correct format using the openssl command. We can come very close…the following demonstrates how to extract the public key from the private key using openssl:

Python Ssh Github

So close! But this is in x.509 format, and even though the OpenSSL library supports PKCS#1 encoding, there is no mechanism to make the command line tools cough up this format.

Python Openssh Windows

Additionally, I am trying for a solution that does not require the private key to be available, which means that in any case I will still have to parse the OpenSSH public key format.