如何从秘密字符串中制作HMAC_SHA256密钥,以便在jose4j中与JWT一起使用



我想制作JWT并用HMAC_SHA256签名。对于这个任务,我必须使用jose4j。我已经尝试生成基于密钥的

SecretKeySpec key = new SecretKeySpec(("secret").getBytes("UTF-8"), AlgorithmIdentifiers.HMAC_SHA512);

但是它生成40比特密钥,而使用HMAC_SHA256进行签名需要512比特密钥。

  • 主要问题-如何使用jose4j与HMAC_SHA512签署代币
  • 由我解决上述问题的方法创建的问题-如何基于秘密字符串制作512位长的密钥
JWA/RFC 7518的第3.2节规定,与哈希输出大小相同或更大的密钥必须与JWS HMAC SHA-2算法一起使用(即,256位用于"HS256"、384bits/"HS384"、512位/"HS512"(。遵循IETF和NIST的建议通常是个好主意。粗略地说,HMAC的安全性来自哈希输出的大小和密钥长度,以较小者为准。因此,使用"0"的字节;秘密";因为密钥给你的密钥只有48位长,而且在实践中,它提供的安全性甚至比这要低得多,因为它是一个字典单词,无论你选择的HMAC SHA-2算法的强度如何。

默认情况下,jose4j强制执行JWA/RFC 7518规定的最小密钥大小。然而,正如汉斯所指出的,有一些方法可以告诉jose4j放宽密钥长度的要求。这可以用JwtConsumer通过在JwtConsumerBuilder上调用.setRelaxVerificationKeyValidation()和用.setDoKeyValidation(false)直接在JsonWebSignature上调用来完成。下面是一个使用HMAC SHA256生成和使用JWT的快速示例,显示了两者。

JwtClaims claims = new JwtClaims();
claims.setExpirationTimeMinutesInTheFuture(5);
claims.setSubject("foki");
claims.setIssuer("the issuer");
claims.setAudience("the audience");
String secret = "secret";
Key key = new HmacKey(secret.getBytes("UTF-8"));
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
jws.setKey(key);
jws.setDoKeyValidation(false); // relaxes the key length requirement
String jwt = jws.getCompactSerialization();
System.out.println(jwt);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
        .setRequireExpirationTime()
        .setAllowedClockSkewInSeconds(30)
        .setRequireSubject()
        .setExpectedIssuer("the issuer")
        .setExpectedAudience("the audience")
        .setVerificationKey(key)
        .setRelaxVerificationKeyValidation() // relaxes key length requirement 
        .build();
JwtClaims processedClaims = jwtConsumer.processToClaims(jwt);
System.out.println(processedClaims);

一种常见的方法是在将机密用作签名密钥之前对其进行散列。

MessageDigest md = MessageDigest.getInstance("SHA-256");
String secret = "secret";
md.update(secret.getBytes("UTF-8"));
byte[] key = md.digest();

另一种选择是放宽对密钥长度的要求,比如:

JwtConsumer jwtConsumer = new JwtConsumerBuilder()
     .setVerificationKey(new HmacKey(secret.getBytes())) 
     .setRelaxVerificationKeyValidation() // allow shorter HMAC keys when used w/ HSxxx algs 
     .build();

为了安全起见,"secret"作为密钥太短且不安全。您可以使用以下代码生成一个安全的密钥作为您的个人密钥。

//Generating a safe HS256 Secret key
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
String secretString = Encoders.BASE64.encode(key.getEncoded());
logger.info("Secret key: " + secretString);

这将起作用:

import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
...
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
String secretString =  Encoders.BASE64.encode(key.getEncoded());
System.out.println("Kex: " + secretString);
...

相关内容

  • 没有找到相关文章

最新更新