Search code examples
python-3.xopensslpython-cryptography

Could not deserialize key data error while loading openssl private key with cryptography module in Python3


I am trying to load a private key generated using OpenSSL using Python's cryptography module.

openssl genrsa -out rootCA.key 4096

The key was generated as:

And its being loaded as:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import load_der_private_key
import os

with open(os.getcwd() + '/rootCA.key', 'rb') as f:
    der_data=bytes(f.read())

key = load_der_private_key(der_data, password=None, backend=default_backend())
print (key)

But I am getting this error:

 File "loading_key.py", line 9, in <module>
    key = load_der_private_key(der_data, password=None, backend=default_backend())
  File "/usr/local/lib/python3.6/dist-packages/cryptography/hazmat/primitives/serialization/base.py", line 28, in load_der_private_key
    return backend.load_der_private_key(data, password)
  File "/usr/local/lib/python3.6/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1080, in load_der_private_key
    password,
  File "/usr/local/lib/python3.6/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1251, in _load_key
    self._handle_key_loading_error()
  File "/usr/local/lib/python3.6/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1309, in _handle_key_loading_error
    raise ValueError("Could not deserialize key data.")
ValueError: Could not deserialize key data.

Could anyone please help regarding this? I can't seem to able to find out the problem, since it seems very straightforward. I could not see any other command in the cryptography module regarding this, so I am not sure if this is an incorrect way to go about things.

EDIT:

For reference purposes, or anyone who is going through a similar issue, this is what the final solution looks like:

with open(os.getcwd() + '/rootCA.key', "rb") as key_file:
         private_key = serialization.load_pem_private_key(
             key_file.read(),
             password=None,
             backend=default_backend()
         )

Solution

  • That openssl genrsa command produces a key in PEM format (it's a text file with begin and END delimiters surrounding the key encoded in base64, you can look at it with any editor or pager).

    However, the load_der_private_key function expects to be given a key in DER format (as raw bytes). That function can't handle a key in PEM format and that's why it throws the error.

    To fix, either pass the content of the PEM file to load_pem_private_key instead of load_der_private_key, or generate a DER representation of your key from the PEM file by running openssl rsa -in RootCA.key -inform pem -out RootCA.der -outform der and then pass the content of that DER file to load_der_private_key.