I'm trying to create a JWT token on JWT.io with ES384 algorithm.
I tried creating a private key in a couple of ways (mostly found online):
openssl ecparam -name secp384r1 -genkey -noout -out privatekey
ssh-keygen -t ecdsa -b 384 -f privatekey
I also tried formatting the key in pkcs8 as such:
openssl pkcs8 -topk8 -in privatekey -out private.pem
The public key I always created with:
openssl ec -in privatekey -pubout -out publickey
But in the end, on JWT.io, it always returns 'invalid signature'. I think I'm missing some basic understanding of what is expected for the 'private key' field in jwt.io but can't figure it out. Any idea what I'm doing wrong?
As an example:
openssl ecparam -name secp384r1 -genkey -noout -out testprivatekey
openssl ec -in testprivatekey -pubout -out testpublickey
Gives me following keys:
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDBkjWOV0LAn2iaHna4uSIY5yoaA5KOvAoGqr9sUNabrbfMuQXDnSUng
xsfTymDJGICgBwYFK4EEACKhZANiAAQySjyVeqVk20TQ8mw0vKZU9jDd0C27virc
BcqHKH+iAYOP76814HxFhC+K5v4eV9uIowUAXi/mdKM5UQq5YW1f21ETM6i9lg31
+SKMx6to499aJe5LJVxTbbuVKADrrgY=
-----END EC PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEMko8lXqlZNtE0PJsNLymVPYw3dAtu74q
3AXKhyh/ogGDj++vNeB8RYQviub+HlfbiKMFAF4v5nSjOVEKuWFtX9tREzOovZYN
9fkijMeraOPfWiXuSyVcU227lSgA664G
-----END PUBLIC KEY-----
When added both in jwt.io: 'invalid signature'.
The curve you're using is correct for use with the ES384 JWS algorithm. The only obstacle is the key encoding/format.
Due to limitations in the Web Cryptography API jwt.io only supports PKCS#8 for EC private keys and SPKI for EC public keys.
The following are example ES384 keys that work as input
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCuAVir5v+2gZv7A3dR
EKT977pKPY+1S+h58Xbzir2gqdUKLuyCUCYJmQ6/7ac4B4ShZANiAASndkjwMCbG
fwEnf3fpjkwdEtdMCDpLEI2G4fokES6J66JxRj3CpmTwLrdJkiPiG0B6pKO+zVft
4j1XajyxhSmyuPpZQo7KaoW2QLEzBZC4M+1ko4cLd9JaSNC9//vcYf4=
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEp3ZI8DAmxn8BJ3936Y5MHRLXTAg6SxCN
huH6JBEuieuicUY9wqZk8C63SZIj4htAeqSjvs1X7eI9V2o8sYUpsrj6WUKOymqF
tkCxMwWQuDPtZKOHC3fSWkjQvf/73GH+
-----END PUBLIC KEY-----
The above was generated with
openssl ecparam -name secp384r1 -genkey -noout -out sec1_ec_p384_private.pem
openssl pkcs8 -topk8 -nocrypt -in sec1_ec_p384_private.pem -out ec_p384_private.pem
rm sec1_ec_p384_private.pem
openssl ec -in ec_p384_private.pem -pubout -out ec_p384_public.pem
It also supports JWK as input.
(private)
{
"kty": "EC",
"x": "p3ZI8DAmxn8BJ3936Y5MHRLXTAg6SxCNhuH6JBEuieuicUY9wqZk8C63SZIj4htA",
"y": "eqSjvs1X7eI9V2o8sYUpsrj6WUKOymqFtkCxMwWQuDPtZKOHC3fSWkjQvf_73GH-",
"crv": "P-384",
"d": "rgFYq-b_toGb-wN3URCk_e-6Sj2PtUvoefF284q9oKnVCi7sglAmCZkOv-2nOAeE"
}
and (public)
{
"kty": "EC",
"x": "p3ZI8DAmxn8BJ3936Y5MHRLXTAg6SxCNhuH6JBEuieuicUY9wqZk8C63SZIj4htA",
"y": "eqSjvs1X7eI9V2o8sYUpsrj6WUKOymqFtkCxMwWQuDPtZKOHC3fSWkjQvf_73GH-",
"crv": "P-384"
}