Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate JSON web token (JWT) with a private key

Tags:

java

openssl

jwt

I'm trying to generate JWT but I'm receiving this error:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out certificate_pub.crt

I'm using the io.jsonwebtoken.Jwts library, and a private key in string form but I'm getting errors.

Map<String, Object> payload = new HashMap<>();
payload.put("iss", orgId);
payload.put("sub", accountId);
payload.put("exp", expirationTime);
payload.put("aud", new 
StringBuilder("Url").append("/c/").append(apiKey).toString());
payload.put(new StringBuilder("Url").append("/s/entt_sdk").toString(), Boolean.TRUE);
return Jwts.builder().setClaims(payload).**signWith**(SignatureAlgorithm.RS256, privateKeyStr).compact();
java.lang.IllegalArgumentException: Base64-encoded key bytes may only be specified for HMAC signatures.  If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.

My private key looks like this:

-----BEGIN PRIVATE KEY-----
sajdkjsadkjsahdkjsadksadkjsadkjs
-----END PRIVATE KEY-----
like image 422
Hari Bisht Avatar asked Oct 05 '19 14:10

Hari Bisht


People also ask

How use JWT private key?

You can insert the private key there to sign a token. When you have an existing token on the left side, you just insert the public key on the right side to verify the token, but if you add a private key, the token is signed using that private key.

Is JWT private key?

Private Key JWT is a method of client authentication where the client creates and signs a JWT using its own private key. This method is described in a combination of RFC 7521 (Assertion Framework) and RFC 7523 (JWT Profile for Client Authentication, and referenced by OpenID Connect and FAPI 2.0 Security Profile.

Who will generate JWT token?

A very common use for JWT — and perhaps the only good one — is as an API authentication mechanism. JWT technology is so popular and widely used that Google uses it to let you authenticate to its APIs. On the client side, you create the token (there are many libraries for this) using the secret token to sign it.


1 Answers

The error is quite straightforward - this method can be used only for Hmac algorihtms. For RSA based algorithms you will have to use signWith(SignatureAlgorithm, Key).

The key that I will use will not be in PEM format - it will be base64 DER encoded String - to do it I had to get rid of the beginning and ending of PEM format for this key - -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- :

MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9/xBGBRhpSBa/
Xc/5CeAQjjVMcXfIFOqeIc/kq7dnsLz+ntTrvTE3fyz0E8J8MLMTNypK7irt8MB0
0Gpm/NJHnLSGqgSqIXAvUbUsxCO8ULSTKLTQs4RiDbUtOWZgacvRN0IYRnN2tDWf
DWTYAElBSValTt/jvHw72BMcLXd8plGQYYD52l6+w/7ENgLG+hNbVewdM/saJKyL
Y/jhRl758XWGw5bCmIYk9BCbUVDLc5PN+iiYoBFTQYwP0Y1ln58vNZ/CDBw2mW3q
TyploxoAdmG86km4EK2mtlhWBaUshfHORxGkWlCXcwazWDoc5QJ24McaYbcQOcPW
lLDgP8MvAgMBAAECggEAHDX6MZtiE4fbsNB6J+06ctrauR4D/hZ0+8PjfX2tvty0
Q05MKTCvVSEyCI/CifQlMs43HmccwrXDrdSgZ+hURMPU3kXyaVyLrssADsSU1cpZ
9ZvOtUpidri4VR23wMsUs1z0GGylilOZvqMbfSMVvXbpQaRjhAohnDUqKT3rBvvd
fqO8KFl8FCgMEbbPvym5tJvrYfe9WalisnrGrrCZoaBmR5dEbjUfWrMg6bMcfPlz
rVaney8+UdFu15RUXTno3mu+glIYz1MyYk6LdlgBrb19gBscykqi0wYhZ312Yk0B
SXx+RIi49oZy7IU4jybzOSqWL79L4rQdvtBrp/dx6QKBgQDn/XeuCATwLdFyeo4/
ksVlhXIp9ykAZSFk/wnapcsvLSV59edI8mkslAwTTbgqPn0hvxVdwf0k23wipkGl
FiujHMCGoeT9ZwYs9uDEkGABATXomr7eC64AEfuUnUZMj3s0BgG5S/mGonlkIlTt
RpvxzMeYnRvLjDXZMP7FKCz0DQKBgQDRqPq+w7MQFBaBMTE7+685QeR+xxGnMipW
Qf579E++ihslGx6LztQnFhbah2VEVCPBq7R/BiEHiW4bA+DiTC8HnMsZi3jhlO9q
yw0DSZUSX8vsgNW2ghJOF9JnZEbptN3RlD11koSvkFZiUuxHYa0n6ti38CwfLxgV
MCuL5XOZKwKBgGi4CqD9L7V3CTdiyPk7eG1mOm1lCxYJkHR1h24yLrCB8YvHC3rr
Kbycq4K/L2WqRXPJPIzQ90L+7F77q2AozNPZM7LSO3qDWc9MNZOlFCD/+eSgjY3P
ueCAPY8NG2GN1vBZ0cdh2yYCC0e/E5TzrYsNg/+I07Yi+V+r9STsCLa1AoGAJnJo
WOcmRQKKBfLxZmCHB2bv8dergw+N9/duJWjt3rEQvUM13Ml22hwQ4M4HYfpT/EXy
eYC0Od+X01houtbhoPG9xNdwuV1Icjr+DeZGcfIjQSF3D1rW5H811EPtRRonuzEF
/DN8JX3AeZNfRM/CoxlL2J8wWB+YuPn2YlcXVbUCgYEAmVETM7+OBW9YKtv6zvKe
OZeZUIDIUZDqZgLd3IT7rikVCedIljWNhroXU1wNMssJPkfiQToGaykUMbBcgZKI
neU2IuYWaLXBN9oAj1u7/YQ0DpPqk/Sb2FpVX5eKfp4cu8XdyezxNuFFsPVdGBhB
xhqJOJuUc/ZKbo5Stc3NXEE=

Here is example of how to read this key and sign JWT with it :

//create payload
Map<String, Object> payload = new HashMap<>();
payload.put("iss", "orgId");
payload.put("sub", "orgId");
payload.put("exp", "orgId");
payload.put("aud", new
StringBuilder("Url").append("/c/").append("key").toString());
payload.put(new StringBuilder("Url").append("/s/entt_sdk").toString(), Boolean.TRUE);

// read key
String privateKeyB64 = Files.lines(Paths.get("src/main/resources/private.key")).collect(Collectors.joining());
byte[] privateKeyDecoded = Base64.getDecoder()
                .decode(privateKeyB64);

//create key spec
PKCS8EncodedKeySpec spec =
                new PKCS8EncodedKeySpec(privateKeyDecoded);

// create key form spec
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(spec);

//create signed JWT - JWS
String jws = Jwts.builder().setClaims(payload).signWith(SignatureAlgorithm.RS256, privateKey).compact();

System.out.println(jws);

Notice I used PKCS8EncodedKeySpec because your key seems to be in PKCS8 format. The output is :

eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJvcmdJZCIsImF1ZCI6IlVybC9jL2tleSIsImlzcyI6Im9yZ0lkIiwiZXhwIjoib3JnSWQiLCJVcmwvcy9lbnR0X3NkayI6dHJ1ZX0.m8ASk4kUNx41csikpd0zALLQTjwG2pc0Ba0D9PGLVbI2NaY0IIXgaVVVJcIERz4ejj_jfq436v6v0_QnxdmvjMAnx88UmHGdrCT0V5MZl008LP4g4LrV-WczNltCUpoJQ-4CW6xkpXD03JIDQAYwaKb-PIOtm-pfLJhPPmxykc8QioueijhI5M__Pq5Nq0JCbkQxfGzxE5m_gJwwq7n290RBGRYH6AHeClaEJhDzLNitIejNvvua4zNNC6S1CHsa4ChaEFfRb9bi-jNEQW27IGhrKRCtuwleFwigl7oTIsyaRWlzuVNYcZHS707Z2o6Mkf9hDo8AGKURUVsJgA8WIg

I tested it on Java 8. For Java 11 I received an error with missing module regarding XML processing.

like image 92
Michał Krzywański Avatar answered Oct 21 '22 10:10

Michał Krzywański