静态密钥为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();