在Spring中使用JWT。使用Jwts.builder().signWith(SignatureAlgorithm, String)
和Jwts.parserBuilder().setSigningKey(String)
设置用于加密JWT的secret,当我把依赖项从jjwt升级到jjwt-api后,IDE提示我方法已被弃用。查看源码,从注释中发现signWith(SignatureAlgorithm, String)
和setSigningKey(String)
均有另外两个重载方法,为了方便,下面只讨论setSigningKey
方法。代码注释中说,setSigningKey(String)
实际就是先使用Decoders.BASE64.decode(String)
方法把String参数转为字节数组,再使用setSigningKey(btye[])
设置加密key。注释中还说,这两个方法将来都会被删除,推荐使用setSigningKey(Key)
方法。从名字上看,setSigningKey(String base64EncodedSecretKey)
方法的参数应该是经过base64编码的字符串。而setSigningKey(btye[])
方法则是把base64编码的字符串解码后的字节数组作为参数。
我的疑问是,为什么用字符串作为参数时,该字符串必须经过base64编码,而用字节数组作为参数时,却反而是经过base64解码的?通常,我们会使用随机字符串作为secret,那么在生成该随机字符串时有什么要求,是否要先生成随机字符串,再将其编码成base64字符串?如果要编码成base64字符串,该如何编码呢?
自己琢磨出来了。
用于加密JWT的secret字符串没有特殊要求。
不过在使用上面提到的以String为参数的方法时,secret字符串需要先经过Base64编码。也就是说,在使用
signWith(SignatureAlgorithm, String)
和setSigningKey(String)
方法前,要先使用Base64对secret编码。可以使用hutool包中Base64Encoder.encode(String)
方法。当使用上面提到的以
byte[]
为参数的方法时,其实不需要先把secret编码为Base64字符串,再把Base64字符串解码为字节数组,直接对secret调用String::getBytes()
方法就可以了。不过既然包已经弃用了以
String
或byte[]
为参数的方法,最好是使用以Key
为参数的方法。要从字符串格式的secret生成Key对象,可以使用jjwt包中Keys.hmacShaKeyFor(byte[])
方法,具体用法如下:SecretKey = Keys.hmacShaKeyFor(secret.getBytes())
。