JSON Web Key (JWK) for public key requires x and y coordinates.

Nicola Tuveri nic.tuv at gmail.com
Mon Dec 23 06:24:42 UTC 2019


Hi Douglas,

I don't think OpenSSL supports the encoding of keys specified in
RFC7518: you are right in believing that the x and y values can be
retrieved from the 'pub:' field of the `-text` output for the key, but
that field conforms to Sec 2.3.4 of the SEC1 standard (which is
referenced also by RFC7518, although they preferred to use a custom
representation for the curve point).

If I am reading RFC7518 correctly, you would need a piece of software
that would take the affine x and y coordinate for the public EC point
encoded as the base64 encoding of the octet representation of a field
element (zero padded to the byte length of the field order).

It is possible to achieve this writing a C/C++ program using the
OpenSSL API, but as far as I know, no OpenSSL CLI tool currently
supports that format.

With a quick glance at Google results though, it seems that many
modules supporting JOSE for NodeJS/Ruby/Erlang/Elixir/Python also have
methods to parse a public key PEM file and transform into an RFC7518
key.
So depending on what language you are using to develop your
application you should be able to call something like
`JOSE::JWK::from_pem_file('pubkey.pem')` and obtain an object
representing the public key that can be exported to the RFC7518
encoding.

In Ruby, for example, using the 'jose' gem, you could:

```sh
$ openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1
-pkeyopt ec_param_enc:named_curve -outform PEM -out
account-privkey-prime256v1.pem
$ openssl pkey -in account-privkey-prime256v1.pem -pubout -out
account-pubkey-prime256v1.pem
$ ruby -e 'require "jose"; puts
JOSE::JWK::from_pem_file("account-pubkey-prime256v1.pem").to_map.to_h'
{"y"=>"vUFxfD2pBMjv-iaX8zKnNeXe2GaZcspLdnyoPzEK89w", "kty"=>"EC",
"crv"=>"P-256", "x"=>"-3zPuCvv1VTw1hs5X4pCLkj3QQjocw9lYEKxqKG27W8"}
```

Bonus answer: I am not an expert on the RAND module of OpenSSL, but
the short answer should be that if you are using the latest release of
OpenSSL, most likely you don't need to worry about seeding manually
the PRNG, as the RAND module should be doing everything it can to
gather the required entropy from the facilities provided by your
platform and feeding it through a state-of-the-art cryptographic PRNG
implementation to obtain the cryptographically secure randomness
needed, e.g. for the key generation above.
Of course I cannot say anything about the functionality provided by
whatever framework you are going to use for the rest of your RFC7518
operations, as what they use depends on their cryptographic backend
(which could be OpenSSL or some other software).



Best regards (and Happy Holidays to you as well)

Nicola Tuveri


More information about the openssl-users mailing list