【问题标题】:JWT decoding say invalid signature even on providing correct "signing" key即使提供正确的“签名”密钥,JWT 解码也会说无效签名
【发布时间】:2018-06-20 11:43:51
【问题描述】:

JWT 标记化让我发疯,或者我用错了。

为了测试并从“jjwt”开始,我正在创建一个简单的 jwt 令牌,下面是代码。

static String createSimpleJWT() {
        String id, issuer, subject;
        id="id";
        issuer="issuer";
        subject="subject";

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id)
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(SignatureAlgorithm.HS256, "signingKey");  //plz note signing key on this line
        return builder.compact();
}

jwt 令牌是

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJpZCIsInN1YiI6InN1YmplY3QiLCJpc3MiOiJpc3N1ZXIifQ._7QGamE-HvREDMJIgbfKEIRv76ZaxwIx2t3RaViSYzth4

正如预期的那样,在随后的执行中,我也会得到相同的 JWT。

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJpZCIsInN1YiI6InN1YmplY3QiLCJpc3MiOiJpc3N1ZXIifQ._7QGE-HvREDMJIgbfKEIRv76ZaxwIx2t3RaViSYzth4

我正在使用 jwt.io 对其进行解码以进行测试- 但很惊讶地看到 jwt 令牌被标记为无效签名,尽管在解码部分提供了正确的签名密钥。

这是 jwt.io 截图 - jwt.io-invalidsignature

任何指针......它会变得混乱。

这篇文章与之前询问的用户忘记或不知道向 jwt.io 提供签名密钥的地方不同 PHP JWT Token Invalid Signature
JWT Token Invalid Signature

【问题讨论】:

    标签: json jwt tokenize jjwt


    【解决方案1】:

    您的问题与https://stackoverflow.com/a/38269014/6371459 类似。

    这是由于.signWith(SignatureAlgorithm.HS256, "secret")。它由 DefaultJwtBuilder 类实现

    public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) 
    

    此方法假定您提供 base64 格式的密钥,并且 secret 不是 base64。当方法从 base64 解码到 byte[] 时,jjwt 使用的 java 转换器提供了字符串 secr 的表示形式,这与 jwt.io

    JWTBuilder.signWith 需要 base64 编码的密钥,但您提供的是纯文本,所以:

    • 在 jwt.io 中插入“signingK”并检查“secret base64 encoded”

    • 提供base64编码的密码

    --

    String signingKeyB64= Base64.getEncoder().encodeToString("signingKey".getBytes("utf-8"));
    JwtBuilder builder = Jwts.builder().setId(id)
                    .setSubject(subject)
                    .setIssuer(issuer)
                    .signWith(SignatureAlgorithm.HS256, signingKeyB64);
    

    我建议生成随机密码而不是使用固定字符串

    Key key = MacProvider.generateKey();
    String signingKeyB64 = Base64.getEncoder().encodeToString(key.getEncoded());
    

    【讨论】:

    • 如果我们在生成token的时候生成了一个随机密码,那么在解码request传入的JWT时调用JWT parse() setSigningKey()如何得到相同的密码?
    • @james 您必须将生成的密钥存储在某个地方才能使用它进行验证。不必为每个token生成一个key,可以暂时重复使用。
    【解决方案2】:

    我在使用这个 JWT 库时遇到了几乎相同的问题,因此我将其更改为另一个库。不知道为什么会这样。我的应用程序用于针对第三方系统进行身份验证。

    试试这个 Lib 并再次检查它,也许这对你有帮助:

    https://github.com/auth0/java-jwt

    【讨论】:

    • 之前使用的是最新的 0.9.0 版本。现在也尝试使用 6、7 和 8 ......不走运。
    • 另一个奇怪的事情,即使在解码器java代码中提供错误的秘密,也没有抛出异常并且解码正常进行。
    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 2018-01-04
    • 2020-01-30
    • 2016-12-29
    • 2021-06-21
    相关资源
    最近更新 更多