3

I have a Private Key with the following format

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIE6TAbBgkqhki....
----END ENCRYPTED PRIVATE KEY-----

How can I convert this in a key with RSA format

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA28jIsb8SAhJritwO....
-----END RSA PRIVATE KEY-----

The current version of cryptography I have is 2.8. Any help is really appreciated. Thanks in advance.

Rahul Goud
  • 147
  • 2
  • 12
  • 1
    Not in python but have you checked [this](https://stackoverflow.com/questions/49230122/encrypted-private-key-to-rsa-private-key)? – Maël Pedretti Apr 29 '21 at 14:08
  • Yeah I did, but I want it to automate it, hence Python. – Rahul Goud Apr 29 '21 at 14:35
  • 2
    What you want to do is to convert a PEM encoded, encrypted PKCS#8 private key to a PEM encoded PKCS#1 private key. Generally you first decode to a Python private key, then reencode it. However, maybe just calling the OpenSSL command line from Python might be a better option in this case. It's a rather strange requirement to convert a a lot of protected private keys to unprotected private keys, by the way. – Maarten Bodewes Apr 29 '21 at 15:05

1 Answers1

5

As described in the comment by Maarten Bodewes, a conversion of a encrypted private key in PKCS#8 format to a private key in PKCS#1 format (both PEM encoded) is possible with OpenSSL. But this can also be done with the Cryptography library.

The Cryptography library supports the import of (encrypted) private keys in PKCS#8 format, PEM encoded, with the method load_pem_private_key() (since version 0.6), e.g.:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

pkcs8Encrypted = b"""-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICzzBJB...
-----END ENCRYPTED PRIVATE KEY-----"""

privateKey = serialization.load_pem_private_key(
    pkcs8Encrypted, 
    b'mypassword',
    default_backend()
)

The export of private keys in PKCS#1 format, PEM encoded is possible with private_bytes() (since version 0.2):

pkcs1 = privateKey.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)

print(pkcs1.decode('utf-8')) # -----BEGIN RSA PRIVATE KEY-----... 

The current version of Cryptography is 3.4.7 (Mar 2021). 2.8 is from Oct 2019, s. Release history. Actually, both methods should therefore be available.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Hi @topaco, thanks for your comment. I did try the same earlier, but somehow its not working for me. Please find the below sample: private_key: b'-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIE6TAbBgk...\n-----END ENCRYPTED PRIVATE KEY-----\n' p_key = serialization.load_pem_private_key(private_key, password=passphrase.encode(), backend=default_backend()) I get the following error: ValueError: Could not deserialize key data. – Rahul Goud Apr 29 '21 at 16:42
  • 1
    @RahulGoud - If the code is running in your environment, the key may be the problem. Then I would try a conversion with OpenSSL, as this is presumably more powerful than the Python implementation. Also, it would be helpful if you could post a **test** key that causes the problem in your environment. – Topaco Apr 29 '21 at 17:45