当验证从php生成的jwt令牌时,jjwt引发签名错误 [英] Jjwt throws signature error when validates a jwt token generated from php

查看:184
本文介绍了当验证从php生成的jwt令牌时,jjwt引发签名错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在使用Java的CAS构建的SSO中添加PHP应用程序. 在对用户进行身份验证之后,SSO将凭据发送到PHP App,并使用以下代码构建令牌:

I need to add a PHP application in a SSO built using a CAS in Java. After authentication of the user, the SSO sends the credintials to the PHP App and the token is built using the code below:

public function getToken(Signer $signer = null, Key $key = null)
    {
        $signer = $signer ?: $this->signer;
        $key = $key ?: $this->key;

        if ($signer instanceof Signer) {
            $signer->modifyHeader($this->headers);
        }

        $payload = [
            $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)),
            $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims))
        ];

        $signature = $this->createSignature($payload, $signer, $key);

        if ($signature !== null) {
            $payload[] = $this->encoder->base64UrlEncode($signature);
        }

        return new Token($this->headers, $this->claims, $signature , $payload);
    }

    private function createSignature(array $payload, Signer $signer = null, Key $key = null)
    {
        if ($signer === null || $key === null) {
            return null;
        }
        return $signer->sign(implode('.', $payload), $key);
    }

因此,我尝试使用Java来验证生成的令牌,如下所示:

So I try to validate the generated token using java, as bellow:

 public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            log.info("Invalid JWT signature.");
            log.trace("Invalid JWT signature trace: {}", e);
            e.printStackTrace();
        }
        ....
    }

要验证签名,jjwt会拆分令牌的3个部分,并尝试使用令牌标头中提供的算法对2个第一"部分进行签名.创建令牌时,此步骤与创建令牌签名的步骤相同.从理论上讲,使用相同的算法,在创建和验证两个步骤中都使用了工资和秘密,签名应该是相同的. 但这并没有发生. 引发以下异常:

To validade the signature, the jjwt splits the 3 parts of the token and tries to sign the 2 firsts parts using the algorithm provided in the header of the token. This step is the same used to create the signature of the token when the token is created. Theoretically, using the same algorithm, paylod and secret in both steps, creation and valitadion, the signature shoud be the same. But it does not happen. The following excpetion is thrown:

io.jsonwebtoken.SignatureException:JWT签名与本地计算的签名不匹配. JWT的有效性不能断言,也不应该被信任.

io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

推荐答案

我将回答我自己的问题. jjwt期望使用base64加密的机密.但是在我的Java代码中,我没有在解析器中设置密码之前对其进行编码.

I will respond my own question. jjwt expects a base64 enconded secret. But in my java code I was not encoding the secret before set it in the parser.

这是jjwt验证令牌签名的方式:

This is how jjwt validate the token signature:

    public boolean isValid(String jwtWithoutSignature, String base64UrlEncodedSignature) {

        byte[] data = jwtWithoutSignature.getBytes(US_ASCII);

        byte[] signature = TextCodec.BASE64URL.decode(base64UrlEncodedSignature);

        return this.signatureValidator.isValid(data, signature);
    }

我在Java代码中所做的更改:

The change I made in my java code:

    secretKey = TextCodec.BASE64URL.encode(secret);
    Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken)

这篇关于当验证从php生成的jwt令牌时,jjwt引发签名错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆