3

我正在使用 JJWT 库生成我的 JWT 令牌。我按如下方式生成我的令牌。我使用虚拟值作为我的密钥。

我们可以假设jwt.security.key=security-key

   @Value("${jwt.security.key}")
    private String key;

    @Value("${ws.issuer}")
    private String issuer;

    static final long ONE_MINUTE_IN_MILLIS=60000;

    static final long TOKEN_DURATION_IN_MIN=30L;

    private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    @Override
    public String issueToken(String userName) {

        long nowMillis = System.currentTimeMillis();
        long expMillis = nowMillis + (ONE_MINUTE_IN_MILLIS * TOKEN_DURATION_IN_MIN);

        return  Jwts
                .builder()
                .setId("01")
                .setIssuedAt(new Date(nowMillis))
                .setHeaderParam("typ","JWT")
                .setSubject(userName)
                .setIssuer(issuer)
                .setExpiration(new Date(expMillis))
                .signWith(signatureAlgorithm, key).compact();

    }

虽然令牌可以成功解码。每次我从 jwt.io 调试器验证它的签名时,它总是导致签名无效。可以在这里看到。

4

1 回答 1

4

security-key不是有效的 Base64 编码字符串。阅读 JavaDoc 和signWith(SignatureAlgorithm, String)方法的参数名称:

/**
 * Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS.
 * 
 * <p>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[])}.</p>
 *
 * @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);

此外,为什么不考虑jwt.io可能会损坏呢?它不是权威的 jwt 工具。

最后,我要注意的是,你永远不应该使用纯文本字符串或随机字符串作为签名密钥。数字签名始终使用字节数组计算。如果您希望密码术是安全的,您应该始终为您正在使用的签名算法使用足够长度的安全随机字节数组。

看 JJWTKeys.secretKeyFor生成足够长且足够强的密钥的方法。

jwt.io站点具有误导性,因为它没有使这一点显而易见,并暗示您可以使用任何旧字符串作为签名密钥。虽然这在技术上是可行的,但您绝对不应该这样做。如果需要将它们表示为字符串,则应始终使用经过 Base64 编码的安全随机字节数组。这就是为什么接受字符串作为键的 JJWT 方法假定它是 Base64 编码的 - 因为如果不是,您可能使用了无效或格式错误的键。

于 2016-08-14T08:28:27.797 回答