How to Create a JWT in Java with the secret base64 encoded and jose4j

1.5k Views Asked by At

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOiJsaWh6NiIsInN1YiI6ImxpaHo2IiwiZXhwIjoxNjQ3OTIwNzU3fQ.voGK_UVv0ezNGj42XSDa-x4XojXr-qwmc-VnB_zZKxXHrQZE1agD-YAfeINnTOg0H8XZ3_qdyQGHcUCf5ruHvA

I use E2ABA91===! as key and check secret base64 encoded on jwt.io, then I want to build it with jose4j

I want jose4j get jjwt result,what should I do . JDK8,

package a;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.JoseException;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class D {
    static String KEY = "E2ABA91===!";
    static String userId = "lihz6";
    static Date date = new Date((1647949518L * 1000));
    // static Date date = new Date((System.currentTimeMillis()/1000*1000) + 3600 * 1000);
    
    public static void main(String[] args) throws JoseException {
       //I want jose4j get jjwt result,what should I do 
        System.out.println(date.getTime());
        jjwt2();//another server use this code and get correct
        jose4j2();//I want use jose4j but get error result
    }
    
    
    static void jjwt2() {
        Map<String, Object> map = new HashMap<>(16);
        map.put("userId", userId);
        String biTokentoken = Jwts.builder()
                .setClaims(map)
                .setSubject(userId)
                .setExpiration(date)
                .signWith(SignatureAlgorithm.HS512, KEY)
                .compact();//jjwt get jwt.io result
        System.out.println(biTokentoken);
    }
    
    
    static void jose4j2() throws JoseException {
        
        JwtClaims jwtClaims = new JwtClaims();
        jwtClaims.setSubject(userId);
        NumericDate now = NumericDate.now();
        now.setValue(date.getTime() / 1000);
        jwtClaims.setExpirationTime(now);
        jwtClaims.setClaim("userId", userId);
        
        HmacKey hmacKey = new HmacKey(KEY.getBytes(StandardCharsets.UTF_8));
        
        JsonWebSignature jsonWebSignature = new JsonWebSignature();
        jsonWebSignature.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA512);
        jsonWebSignature.setPayload(jwtClaims.toJson());
        jsonWebSignature.setKey(hmacKey);
        jsonWebSignature.setDoKeyValidation(false);
        
        String biTokentoken = jsonWebSignature.getCompactSerialization();
        System.out.println(biTokentoken);
    }
}

pom.xml

   <dependency>
            <groupId>org.bitbucket.b_c</groupId>
            <artifactId>jose4j</artifactId>
            <version>0.7.11</version>
        </dependency>
    
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
3

There are 3 best solutions below

1
On

You're telling jwt.io that your secret is base64-encoded, but then you base64-encode the string yourself when using it in your code.

So, jwt.io decodes the E2ABA91===! string and uses the result as the secret key, and you encode E2ABA91===! and use the result as the secret key. That's why you get different results.

Uncheck the secret base64 encoded on jwt.io and use this in your code:

HmacKey hmacKey = new HmacKey(KEY.getBytes(StandardCharsets.UTF_8));

You should then get the same results in your code and on jwt.io.

0
On

The jjwt signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) expects a base64 encoded secret and base64 decodes it prior to use. Jose4j just uses the key it's given. So, to get the same result, you need to base64 decode it first (with a decoder that will ignore the non-base64 character). Replace HmacKey hmacKey = new HmacKey(KEY.getBytes(StandardCharsets.UTF_8)); with HmacKey hmacKey = new HmacKey(Base64.decode(KEY)); to do that.

0
On

Also, hopefully you aren't using actual production keys here but E2ABA91===! is much much too short to be a secure HMAC secret.