如何使用secret base64编码和jose4j在Java中创建JWT



https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzMiJ9.eyJ1c2VySWQiOiJsaWh6NiIsInN1YiI6ImxpaHo2IiZXhwIjoxNjQ3OTIWNzU3fQ.voGK_UVv0ezNGj42XSDa-x4XoXr-qwmc-VnB_zZKxXHrQZE1agD-YAfeINnTOg0H8XZ3_qdyQGHcUCf5ruHvA

我使用E2ABA91===!作为密钥,并在jwt.io上检查secret base64 encoded,然后我想用jose4j 构建它

我想让jose4j得到jjwt的结果,我该怎么办。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>

您告诉jwt.io您的秘密是base64编码的,但在代码中使用字符串时,您自己对其进行base64编码。

因此,jwt.io对E2ABA91===!字符串进行解码并将结果用作密钥,然后对E2ABA91===!进行编码并将结果作为密钥。这就是为什么你会得到不同的结果。

取消选中jwt.io上的secret base64 encoded,并在代码中使用它:

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

然后,您应该在代码和jwt.io.上获得相同的结果

jjwtsignWith(SignatureAlgorithm alg, String base64EncodedSecretKey)需要一个base64编码的秘密,并在使用前由base64解码。Jose4j只是使用它给出的密钥。因此,要获得相同的结果,您需要首先对其进行base64解码(使用将忽略非base64字符的解码器(。将HmacKey hmacKey = new HmacKey(KEY.getBytes(StandardCharsets.UTF_8));替换为HmacKey hmacKey = new HmacKey(Base64.decode(KEY));

此外,希望您在这里没有使用实际的生产密钥,但E2ABA91===!太短,无法作为安全的HMAC密钥。

最新更新