Java 如何从秘密字符串中生成HMAC_SHA256密钥,以便与jose4j中的JWT一起使用?

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签署令牌 我解决上述问题的方法产生的问题-如何基于

我想生产JWT并与HMAC_SHA256签署。 对于这项任务,我必须使用。 我已尝试使用以下方法基于机密生成密钥:

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);