How to get a JSON Web Key (JWK) from a PEM-encoded X.509 certificate or keys

Developers working with JOSE and JWT may occasionally may need to create a public JWK or a public / private JWK from a PEM-encoded X.509 certificate, a public key, a private key, or a matching pair thereof.

The JWK.parseFromPEMEncodedObject method can take care of that. It parses a string of one or more of the following PEM-encoded objects to create an RSA or EC JWK:

  • X.509 certificate (PEM header: BEGIN CERTIFICATE)
  • PKCS#1 RSAPublicKey (PEM header: BEGIN RSA PUBLIC KEY)
  • X.509 SubjectPublicKeyInfo (PEM header: BEGIN PUBLIC KEY)
  • PKCS#1 RSAPrivateKey (PEM header: BEGIN RSA PRIVATE KEY)
  • PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY)
  • Matching pair of the above, e.g. X.509 certificate with PKCS#8 encoded private key.

Requires Nimbus JOSE+JWT 6.2+.

// PEM-encoded private RSA key generated with
// openssl genpkey -algorithm RSA -out priv.pem -pkeyopt rsa_keygen_bits:2048

String pemEncodedRSAPrivateKey =
"-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCjknN/LTKuPvXU
bvLvyAwIs7I189CC+JErIOWwYzE1zRRLn7zNbG+UQJFqVorWm/84OqX/iC9HYudo
r4qFfT67Fynfs5/OMzbqp7ECX24oKF1G919bUHY8KrJY4CUJhgo4FOda3PuzbmEd
/POB6OcQ2vyJg1SsGY5REfheIaZ+AHVlTaze6HvejNJWE29iVIBxd0a4cWy9T4xt
DS5+Z9juoN+l8QvPjFaYenPzWgOqyw5Fsgkulv++M4A/htPX3iFWQNV1Mix9Y/aS
jbi8ft5+rlt6+llVT87fSgdeT9ZCmceIjwtZW+Zk6dlknXRoTI5q6PZfAFVDKhFN
RKdbSP03AgMBAAECggEAE2aCVlopAausAocqPzBN5RZTE70YRQBwT1o2g+Yv5v6s
4o9OmFq9HStPU/pxuySDb8rc92LSoLflVHBFkLGbKBuGNucaFB3U7J35C5v/97lZ
3tnmMHFppJc30fy7x9ZjDeXEzu0Y2V5FHIZs50KVbVVb0H+IImVhkNH90ERTd+wr
dbQ2lVg+lv86depJ5YhKs7iDbFnztx+OAdHrAo6qEff1gODv+9JK172pBmZsb+j6
l/8FSWJN57FfV61QuaKWezS3ASvxDWsOlI7QLuQwOzg4J4LioBsdE+Q3uHhkx6oF
f/hyYkexsnAl933C/VETK/9tjQf6nBHa29i1nq9k+QKBgQDM/EXj8UR7CJ9cINY4
QLuMDT4qPgIPjVccWJsv/roL43SYZ1NSs7FcfnRWQgCEtAClMXY8E6Q0zMiRRTu0
eQkHJabC0R8HZbF3AKj7zMwTj9X6qm4mondXsqJ0k+YqDlEz2fHXbABHAodL1nlu
wC52I+Nk+ZmLTBsVd1SFgnM8kwKBgQDMR7YheIf6Z8zwuDpbM09fCHXe5SnWSP3m
kN/WGvnTelvi1SUv8cn1+9bc17yJEF35M4i6Fracox+LlGfDJ8neKDJ0MlqKH7Jd
244YiXUaMWQbZcXLx052vwF/Vi7gVnFxdqCM7Nx/AV1vTN+Z7OH5JuQOM+qazR4a
YDYaSsFHTQKBgDtv7ugQXlX6gxLYpqT7CCas9FiVUE2oIxkiDCWXi+TEmFtUopF5
bzUtqZgVXUcdVo6P0APNgjCZLJMK6ywCaH69CSS2NHQVpaam91jD4mzNqTMc1gG3
3Dj+oCKDfBq3ug355SkctNviPM7dqqpVaWNyNo5h3YbJk5Te3BA2aimnAoGAEdqy
sHo4aEpqPx/a+d2iMkwrATBGV9RJXL2M0snIzBMFtO2sMmSPolBAl0zDzbcAf6dh
a+JQU6BuQWTXLNdtbV1WC5HbF/dtP4bRBJP/CCsI9NwQTZ893GMVXmvJ7RGhGKml
nquVGgSkhfXSFUH+/ifIBvXCq4UB/IwsLmAaRIECgYAeX/Lc1r2TWySP0ny+Ra+H
fUUh3gRV/FFEnVfTiyIcP3UL4ikPOCXrDaIE8QOPs5hUzzen5Vo2NG66LyzgH2HG
NAsWO4FEfeuh1jOn9Nz+FIvcATdB2GFYT7qRb44gNq9yWj7Dx9BFByLXht4XM1cH
n3lLUx3lpr32I+zijs25AQ==
-----END PRIVATE KEY-----";

// Parse PEM-encoded key to RSA public / private JWK
JWK jwk = JWK.parseFromPEMEncodedObjects(pemEncodedRSAPrivateKey);

assertEquals(KeyType.RSA, jwk.getKeyType());
assertTrue(jwk.isPrivate());