静态密钥为byte ,Key还是String?

我已经开始使用JJWT在我的服务器应用程序上处理JWT。

我的JWT秘密将存储在resources文件夹中,我将使用Properties类加载秘密。

JJWT提供了三种签名JWT的方法,一种使用byte[] ,另一种使用String ,另一种使用Key

 JwtBuilder signWith(SignatureAlgorithm var1, byte[] var2); JwtBuilder signWith(SignatureAlgorithm var1, String var2); JwtBuilder signWith(SignatureAlgorithm var1, Key var2); 

问题:关于安全性,字符集和其他问题,我应该使用哪些建议?

有一段时间,我站在String ,因为Properties返回一个String

用于signWith(SignatureAlgorithm var1, String var2)的JavaDoc signWith(SignatureAlgorithm var1, String var2)表示期望,甚至直观地命名方法参数:

 /** * Signs the constructed JWT using the specified algorithm with * the specified key, producing a JWS. * * 

* This is a convenience method: the string argument is first * BASE64-decoded to a byte array and this resulting byte array is * used to invoke {@link #signWith(SignatureAlgorithm, byte[])}. *

* * @param alg the JWS algorithm to use to digitally * sign the JWT, thereby producing a JWS. * * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific * signing key to use to digitally sign * the JWT. * * @return the builder for method chaining. */ JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey);

因此,此方法期望字符串参数是Base64编码的密钥字节数组。 它不会假设一般字符串(例如用户密码)作为签名密钥。 JJWT采用Base64编码,因为如果您指定的字符串密码不是 Base64编码的,那么您可能正在使用格式不良或弱密钥。

JWT JWA规范要求HMAC签名密钥的长度等于或大于签名字节数组长度。

这意味着:

 | If you're signing with: | your key (byte array) length MUST be: | | ----------------------- | ------------------------------------- | | HMAC SHA 256 | >= 256 bits (32 bytes) | | HMAC SHA 384 | >= 384 bits (48 bytes) | | HMAC SHA 512 | >= 512 bits (64 bytes) | 

许多在线JWT网站和工具只是弄错了 – 它们允许您认为您可以输入或使用任何旧字符串并且您很好。 有些甚至甚至用密钥这个词预先填充了密钥(显然是一个坏主意,甚至不符合规范,因为它太短了!)。

因此,为了帮助您简化此操作,JJWT提供了一个实用程序,可帮助您生成足够的安全随机密钥,以便通过io.jsonwebtoken.impl.crypto.MacProvider类进行符合规范的签名。

查看各种generateKey方法,了解如何为HMAC签名生成良好的,符合规范的密钥。 例如:

 //creates a 256-bit secure-random key: MacProvider.generateKey(SignatureAlgorithm.HS256); //creates a 384-bit secure-random key: MacProvider.generateKey(SignatureAlgorithm.HS384); //creates a 512-bit secure-random key (the default): MacProvider.generateKey(); 

如果您想将这些生成的密钥存储为String,您可能会对它们进行Base64编码:

 SecretKey key = MacProvider.generateKey(); byte[] keyBytes = key.getEncoded(); String base64Encoded = TextCodec.BASE64.encode(keyBytes); 

但请注意:生成的base64Encoded字符串被认为是安全的, 无法向任何人显示。 Base64编码不是加密 – 值仍然需要保密。 你如何做到这一点取决于你(加密等)。

现在,当创建JWS时,您可以传入base64Encoded值,JJWT知道base64首先解码它以获取实际字节,然后用于计算签名:

 Jwts.builder() //... .signWith(SignatureAlgorithm.HS512, base64Encoded) .compact();