Skip to content
Advertisement

Python import of ECC private key in PEM encoding fails

I’m running Python version 3.8.2 and using pycryptodome version 3.9.9 to import an ECC private key in PEM encoding for later signing some data.

The following EC private key is a sample key, and I’m using it for several cross-platform projects [e.g. Java, PHP, NodeJs] and it works without any problem (it’s a NIST P-256 / secp256r1-key) key:

ecprivatekey.pem:

JavaScript

Using this key in Python is failing:

JavaScript

Using a ASN1-dumper I see:

JavaScript

Now I’m converting this PEM-file to a DER-file using OpenSSL and encode the result in Base64 for using in Python:

JavaScript

This is the result:

JavaScript

Running my import it imports the key successfully:

JavaScript

The last step is to “reconvert” the DER encoded file to a PEM-encoded one:

JavaScript

These are the results of the conversion and the ASN1-dump:

JavaScript

The reconverted key can get imported:

JavaScript

So my question: what is “wrong” with my EC private key so that it runs within Java / PHP / NodeJs-Crypto / WebCrypto but not in Python ? Or much better: how can I import my existing EC private key in Python without any further (external) conversion ?

This is the full source of my import test program:

JavaScript

Advertisement

Answer

The reason for the failure to import my EC private key is very simple – my EC key contained (only) the private key but not the public key. This seems to be okay for Java / PHP / NodeJs-Crypto / WebCrypto (they “derive” the public key under the hood) but not in Python.

I ran into the same problem when I tried to import my EC private key in Dart (using PointyCastle & Basics_Utils), after that I generated a complete new key pair with OpenSSL, the PKCS#8 encoded key has this structure (the additional BIT STRING at the end is the public key):

JavaScript
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement