1

I am trying to load a passphrase-protected private SSH key from a file using the cryptography Python module. However, I'm not exactly sure how to proceed. The following yields a Crypto.Util.Padding.PaddingError: Padding is incorrect. error.

def importPrivateKey(private_key,passphrase):
  """
  Imports the private key in an RSA object and generates the hash.
  """

  # -- Test with pgcrypto (now deprecated) -- WORKS
  with open(private_key, 'r') as private_key_file:
    key = RSA.importKey(private_key_file.read(),passphrase=passphrase)

  print(key)

  # -- Test with cryptography (active) -- FAILS
  with open(private_key,'r') as private_key_file:
    key = load_pem_private_key(private_key_file.read(),password=passphrase,backend=RSABackend())

  print(key)
  SecureString.clearmem(passphrase)

  return key

You can see from the snippet that I have working solution using the pycrypto module, but this module has not been updated in 5 years now. The code that uses cryptography fails with the aforementioned error.

I know there is load_public_ssh_key deserialization function, but this seems to operate on decrypted keys, hence my choice of load_pem_private_key.

Is it possible to load both private/public keys with the cryptography module?

  • This is indeed an interesting Q/A pair, but IMHO it would be more on topic on SO. – Serge Ballesta Jan 25 at 15:12
1

Like any beginner, I made this more complicated that it needed to be, and didn't read the documentation properly.

The key must be read as bytes ('rb'), and the passphrase must also be bytes-like, as per the documentation.

import SecretString
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_ssh_public_key, load_pem_private_key
from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.hazmat.primitives.serialization import PublicFormat

def importPrivateKey(private_key,passphrase):
  """
  Imports the private key in an RSA object and generates the hash.
  """
  with open(private_key,'rb') as private_key_file:
    key = load_pem_private_key(private_key_file.read(),
                               password=passphrase.encode(),
                               backend=default_backend())

  public_key = key.public_key()

  print(public_key.public_bytes(Encoding.OpenSSH,PublicFormat.OpenSSH))
  SecureString.clearmem(passphrase)

  return key

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.