How to generate SSH key pairs with Python How to generate SSH key pairs with Python python python

How to generate SSH key pairs with Python


Use cryptography! pycrypto is not in active development anymore and if possible you should be using cryptography. Since June it's possible to generate SSH public keys as well:

from cryptography.hazmat.primitives import serialization as crypto_serializationfrom cryptography.hazmat.primitives.asymmetric import rsafrom cryptography.hazmat.backends import default_backend as crypto_default_backendkey = rsa.generate_private_key(    backend=crypto_default_backend(),    public_exponent=65537,    key_size=2048)private_key = key.private_bytes(    crypto_serialization.Encoding.PEM,    crypto_serialization.PrivateFormat.PKCS8,    crypto_serialization.NoEncryption())public_key = key.public_key().public_bytes(    crypto_serialization.Encoding.OpenSSH,    crypto_serialization.PublicFormat.OpenSSH)

Note: You need at least version 1.4.0.

Note: If your SSH client does not understand this private key format, replace PKCS8 with TraditionalOpenSSL.


Just in case there are any future travellers looking to do this. The RSA module support writing out the public key in OpenSSH format now (possibly didn't at the time of earlier posts). So I think you can do what you need with:

from os import chmodfrom Crypto.PublicKey import RSAkey = RSA.generate(2048)with open("/tmp/private.key", 'wb') as content_file:    chmod("/tmp/private.key", 0600)    content_file.write(key.exportKey('PEM'))pubkey = key.publickey()with open("/tmp/public.key", 'wb') as content_file:    content_file.write(pubkey.exportKey('OpenSSH'))

The files are opened with a 'wb' as the keys must be written in binary mode.Obviously don't store you're private key in /tmp...


Edit 05/09/2012:

I just realized that pycrypto already has this:

import osfrom Crypto.PublicKey import RSAkey = RSA.generate(2048, os.urandom)print key.exportKey('OpenSSH')

This code works for me:

import osfrom Crypto.PublicKey import RSAkey = RSA.generate(2048, os.urandom)# Create public key.                                                                                                                                               ssh_rsa = '00000007' + base64.b16encode('ssh-rsa')# Exponent.                                                                                                                                                        exponent = '%x' % (key.e, )if len(exponent) % 2:    exponent = '0' + exponentssh_rsa += '%08x' % (len(exponent) / 2, )ssh_rsa += exponentmodulus = '%x' % (key.n, )if len(modulus) % 2:    modulus = '0' + modulusif modulus[0] in '89abcdef':    modulus = '00' + modulusssh_rsa += '%08x' % (len(modulus) / 2, )ssh_rsa += moduluspublic_key = 'ssh-rsa %s' % (    base64.b64encode(base64.b16decode(ssh_rsa.upper())), )