Java 如何从秘密字符串中生成HMAC_SHA256密钥,以便与jose4j中的JWT一起使用?
我想生产JWT并与HMAC_SHA256签署。 对于这项任务,我必须使用。 我已尝试使用以下方法基于机密生成密钥:Java 如何从秘密字符串中生成HMAC_SHA256密钥,以便与jose4j中的JWT一起使用?,java,encryption,jwt,jose4j,Java,Encryption,Jwt,Jose4j,我想生产JWT并与HMAC_SHA256签署。 对于这项任务,我必须使用。 我已尝试使用以下方法基于机密生成密钥: SecretKeySpec key = new SecretKeySpec(("secret").getBytes("UTF-8"), AlgorithmIdentifiers.HMAC_SHA512); 但它生成40位密钥,而使用HMAC_SHA256签名需要512位密钥 主要问题-如何使用jose4j与HMAC_SHA512签署令牌 我解决上述问题的方法产生的问题-如何基于
SecretKeySpec key = new SecretKeySpec(("secret").getBytes("UTF-8"), AlgorithmIdentifiers.HMAC_SHA512);
但它生成40位密钥,而使用HMAC_SHA256签名需要512位密钥
- 主要问题-如何使用jose4j与HMAC_SHA512签署令牌
- 我解决上述问题的方法产生的问题-如何基于秘密字符串生成512位长的密钥
- 一种常见的方法是在将秘密用作签名密钥之前对其进行哈希运算
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();
表示必须在JWS HMAC SHA-2算法中使用与哈希输出大小相同或更大的密钥(即,256位表示“HS256”、384bit/“HS384”和512位/“HS512”)。遵循IETF和NIST的建议通常是个好主意。粗略地说,HMAC的安全性来自散列输出的大小和密钥长度,以较小者为准。因此,使用“secret”的字节作为密钥可以得到一个只有48位长的密钥,实际上,它的安全性甚至比这个密钥要低得多,因为它是一个字典单词,不管您选择的HMAC SHA-2算法有多强
默认情况下,强制执行JWA/RFC 7518规定的最小密钥大小。然而,正如Hans指出的,有一些方法可以告诉jose4j放宽关键长度要求。这可以通过JwtConsumer
在JwtConsumerBuilder
上调用.setRelaxVerificationKeyValidation()
和在JsonWebSignature
上直接调用.setDoKeyValidation(false)
来完成。下面是一个使用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);