[Cryptography-dev] Loading a Curve25519 X.509 key

Saurabh Kapoor saurabh at fintify.com
Thu Mar 11 03:20:02 EST 2021


Thanks Alex and Paul.

The functions load_pem_{public,private}_key work well for x25519 keys that
are written out using openssl's key generator:

   1. For private key: `openssl genpkey -algorithm x25519 > pri_key.pem`
   2. For public key: `openssl pkey -in pri_key.pem -pubout -out
   pub_key.pem`

However, we receive this public key from a service written in Java, which
uses BouncyCastle's library to encode the key.
Apparently, in these keys the curve is not explicitly named and that causes
load_pem_{public_private}_key to fail with the following error (call stack
attached in callstack.txt):

NotImplementedError: ECDSA keys with unnamed curves are unsupported at this
time

These same public/private keys generated by the sender can be opened using
`openssl asn1parse ..` command and what's more, when I generate the public
key from the private key using `openssl pkey -in <> -pubout -out <>` I get
the exact same public key back ! (attached the sample java_pri_key.pem and
java_pub_key.pem). That confirms that at the openssl layer it's able to
recognize the private key and output a public key in the same format.

So my question is: how can I load the sender's pub_key.pem into a
X25519PublicKey? If that's not possible, any suggestions for how else can
I, in Python, load the keys and decrypt data received from the Java service?

regards,
Saurabh

On Thu, Mar 11, 2021 at 12:47 AM Paul Kehrer <paul.l.kehrer at gmail.com>
wrote:

> Yes, load_{pem,der}_{public,private}_key can load
> ed25519/ed448/x25519/x448 keys as well as long as they are in
> PKCS8/subjectPublicKeyInfo formats. We should fix those docs.
>
> -Paul
>
> On Wed, Mar 10, 2021 at 11:05 AM Alex Gaynor <alex.gaynor at gmail.com>
> wrote:
> >
> > Hi Saruabh,
> >
> > I think
> https://cryptography.io/en/latest/hazmat/primitives/asymmetric/serialization.html#cryptography.hazmat.primitives.serialization.load_pem_public_key
> > should work. Notwithstanding the docs, I believe it'll load an
> > X25519PublicKey :-) If that works for you, let us know and I'll make
> > sure we fix those docs.
> >
> > Alex
> >
> > On Wed, Mar 10, 2021 at 11:56 AM Saurabh Kapoor <saurabh at fintify.com>
> wrote:
> > >
> > > Hi,
> > >
> > > A service we communicate with sends us their Curve25519 public key as
> a PEM file. The key is DER encoded and the format is X.509's
> SubjectPublicKeyInfo.
> > >
> > > We would like to create a
> cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey for this
> object but I am unable to find the routines to load such keys.
> X25519PublicKey.load_public_bytes(..) expects a raw key.
> > >
> > > Using the following openssl command I can examine the key: openssl
> asn1parse -in pub_key.pem
> > >
> > > Any suggestions on how my service written in Python can load this kind
> of a public key? I've also posted a slightly more detailed question here:
> https://stackoverflow.com/questions/66492939/python-decoding-an-ecdh-curve-25519-public-key-encoded-as-a-pem-file
> > >
> > > regards,
> > > Saurabh
> > > _______________________________________________
> > > Cryptography-dev mailing list
> > > Cryptography-dev at python.org
> > > https://mail.python.org/mailman/listinfo/cryptography-dev
> >
> >
> >
> > --
> > All that is necessary for evil to succeed is for good people to do
> nothing.
> > _______________________________________________
> > Cryptography-dev mailing list
> > Cryptography-dev at python.org
> > https://mail.python.org/mailman/listinfo/cryptography-dev
> _______________________________________________
> Cryptography-dev mailing list
> Cryptography-dev at python.org
> https://mail.python.org/mailman/listinfo/cryptography-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/cryptography-dev/attachments/20210311/5bd6caf0/attachment-0001.html>
-------------- next part --------------
Traceback (most recent call last):
  File "/home/saurabh/f/om/crypto/fincrypt/crypto.py", line 107, in __init__
    key = load_pem_public_key(pem_bytes)
  File "/home/saurabh/.pyenv/versions/txnanalytics/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 25, in load_pem_public_key
    return backend.load_pem_public_key(data)
  File "/home/saurabh/.pyenv/versions/txnanalytics/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1231, in load_pem_public_key
    return self._evp_pkey_to_public_key(evp_pkey)
  File "/home/saurabh/.pyenv/versions/txnanalytics/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 729, in _evp_pkey_to_public_key
    return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey)
  File "/home/saurabh/.pyenv/versions/txnanalytics/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ec.py", line 272, in __init__
    sn = _ec_key_curve_sn(backend, ec_key_cdata)
  File "/home/saurabh/.pyenv/versions/txnanalytics/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ec.py", line 43, in _ec_key_curve_sn
    raise NotImplementedError(
NotImplementedError: ECDSA keys with unnamed curves are unsupported at this time
-------------- next part --------------
A non-text attachment was scrubbed...
Name: java_pri_key.pem
Type: application/x-x509-ca-cert
Size: 839 bytes
Desc: not available
URL: <https://mail.python.org/pipermail/cryptography-dev/attachments/20210311/5bd6caf0/attachment-0002.crt>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: java_pub_key.pem
Type: application/x-x509-ca-cert
Size: 471 bytes
Desc: not available
URL: <https://mail.python.org/pipermail/cryptography-dev/attachments/20210311/5bd6caf0/attachment-0003.crt>


More information about the Cryptography-dev mailing list