0

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>
abc45628
  • 51
  • 7
  • there are some things unclear with your last edit. a) in the [ `signWith`](https://github.com/jwtk/jjwt#signaturealgorithm-override) function, the algorithm parameter is the second one, not the first. b) the `signWith` function does not automatically decode a base 64 key, you would have to do it manually. So I doubt that the code is complete and working. – jps Mar 22 '22 at 10:03
  • @jps another server use jjwt-root 0.9.1 with sample code and get jwt.io result – abc45628 Mar 22 '22 at 10:38
  • besides the unclear details in the jjwt code (which you didn't clear up), the used key `E2ABA91===!` is not even valid base64 code. (sorry, didn't pay attention to it earlier). So it really doesn't make much sense to replicate a result that is based on undefined behavior. I just tried, and it seems that jwt.io just ignores the last characters (`=!`), which make the base64 code invalid. – jps Mar 22 '22 at 10:56
  • because impossible to update auth server(auth server belong another team), I think I had to use their code to build jwt – abc45628 Mar 22 '22 at 16:03
  • 1
    I tested this in Python. If you create a token with identical header and payload and then base64- decode the given key before using it to sign, the result is a token with identical signature. Michal told you already that you do different things with the key, treating it as base64 encoded on jwt.io, but then encoding it again in your Java code. In your updated question, you removed the encoding part, but you're still not decoding it. The checkbox on jwt.io says, "the key is Base64 encoded, decode it first" and you have to do the same in your code. Decode the key! – jps Mar 23 '22 at 11:31

3 Answers3

0

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.

Michal Trojanowski
  • 10,641
  • 2
  • 22
  • 41
0

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.

Brian Campbell
  • 2,293
  • 12
  • 13
0

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

Brian Campbell
  • 2,293
  • 12
  • 13