cryptography icon indicating copy to clipboard operation
cryptography copied to clipboard

load_pem_privatekey may not support PKCS#8 v2

Open Myse1f opened this issue 3 years ago • 7 comments

I'm using cryptophy 36.0.0, and trying to use it to load private key from pem file.

When I use load_pem_private_key(pem.encode(), password=None) to load pem file, the pem data is in PKCS#8 v2 format, RFC 5958:

-----BEGIN PRIVATE KEY-----
MFMCAQEwBQYDK2VwBCIEIGQqNAZlORmn1k4QrYz1FvO4fOQowS3GXQMqRKDzmx9P
oSMDIQCrO5iGM5hnLWrHavywoXekAoXPpYRuB0Dr6DjZF6FZkg==
-----END PRIVATE KEY-----

it pop errors like:

key = load_pem_private_key(pem.encode(), password=None)
  File "/usr/local/lib/python3.9/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 22, in load_pem_private_key
    return ossl.load_pem_private_key(data, password)
  File "/usr/local/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 823, in load_pem_private_key
    return self._load_key(
  File "/usr/local/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1070, in _load_key
    self._handle_key_loading_error()
  File "/usr/local/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1129, in _handle_key_loading_error
    raise ValueError(
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=218529960, lib=13, reason=168, reason_text=b'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag'), _OpenSSLErrorWithText(code=218640442, lib=13, reason=58, reason_text=b'error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error'), _OpenSSLErrorWithText(code=151498765, lib=9, reason=13, reason_text=b'error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib')])

I notice that openssl genpkey -algorithm ED25519 generate pkcs8 v1 format private key. For example:

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIA818EvzMRV4D2Ty+UfTFmQyhVpw4vL+m3xTSzmLItTE
-----END PRIVATE KEY-----

which I can successfully load by using load_pem_private_key.

I want to know whether cryptography support pkcs8 v2 format private key. Or could I convert pkcs8 v2 to v1 by cryptography?

Myse1f avatar Dec 26 '21 12:12 Myse1f

We use OpenSSL to load these keys so either we're missing some paths to load this type or else OpenSSL itself doesn't support this. I've never seen a key of this type before, so I'm very curious to know what generates keys in this form.

reaperhulk avatar Dec 26 '21 13:12 reaperhulk

Actually, I'm trying to build an application initially written in rust, and convert it to python version. So I need to parse pem file generated by rust version. I used Ed25519KeyPair::generate_pkcs8 to generate keys in PKC8 v2 format.

I am not familar with low level cryptography. Neither do I know whether openssl support this form.

Myse1f avatar Dec 26 '21 13:12 Myse1f

Just some followup here for tracking: OpenSSL does not currently support this (https://github.com/openssl/openssl/issues/10468) but has an open PR with a "post-3.0" milestone (https://github.com/openssl/openssl/pull/13942).

As it stands we won't be able to support this until OpenSSL does unless we choose to hoist our key deserialization routines out of OpenSSL, which has a bunch of challenges (not least how we'd handle encrypted keys while still using OpenSSL's facilities for that).

reaperhulk avatar Apr 03 '22 08:04 reaperhulk

OpenSSL3 supports working with private keys in PKCS#8 format, while PKCS#1 format is already deprecated and not supported in many places. The blocked-on-upstream tag is no longer relevant. It is a pity that pyca/cryptography does not keep up with current security standards.

m1024 avatar Feb 29 '24 18:02 m1024

We've supported PKCS#8 formatted keys for years. This issue specifically refers to PKCS#8 v2, and as you can see from the links @reaperhulk included, that functionality is not available in OpenSSL.

alex avatar Feb 29 '24 18:02 alex

I have an encrypted private key in PKCS#8 format. In openssl 3.0.2, the command "openssl rsa -in ***.key" successfully decrypts this key. When I try to decrypt it via ca/cryptography library using the load_pem_private_key method, I get an error. At the same time if I use the key generated by openssl 1.1.1 the key is successfully imported.

m1024 avatar Feb 29 '24 18:02 m1024

That has nothing to do with this issue. If you'd like to file a separate issue with steps for us to reproduce, we'd be happy to take a look.

On Thu, Feb 29, 2024 at 1:36 PM Макар @.***> wrote:

I have an encrypted private key in PKCS#8 format. In openssl 3.0.2, the command "openssl rsa -in ***.key" successfully decrypts this key. When I try to decrypt it via ca/cryptography library using the load_pem_private_key method, I get an error. At the same time if I use the key generated by openssl 1.1.1 the key is successfully imported.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

-- All that is necessary for evil to succeed is for good people to do nothing.

alex avatar Feb 29 '24 18:02 alex