Jjwt throws signature error when validates a jwt token generated from php

╄→гoц情女王★ 提交于 2021-01-29 17:38:57

问题


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);
    }

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();
        }
        ....
    }

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 signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.


回答1:


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.

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);
    }

The change I made in my java code:

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


来源:https://stackoverflow.com/questions/57297249/jjwt-throws-signature-error-when-validates-a-jwt-token-generated-from-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!