JWT签名验证

时间:2015-03-23 11:11:09

标签: java jwt

我想使用共享密钥验证Sender的JSON有效负载。我浏览了一些网站并提出了这个简单的代码,只验证签名。

package com.toyota.com;

import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class JWTVerify {
    private final Base64 decoder = new Base64();
    String secret="anandan";
    private final byte[] bsecret=secret.getBytes();
    public static void main(String args[]) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException
    {
        String token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmNvbSIsIm5iZiI6MTQyNzEwNjIwNCwiZXhwIjoxNDI3MTA5ODA0LCJpYXQiOjE0MjcxMDYyMDQsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3RlciJ9.BlVNHzDHelLyFCFurP72U5uPVrL8ae8EEIIuVCfSZM8";
        String[] pieces = token.split("\\.");
        JWTVerify jwt=new JWTVerify();
        jwt.verifySignature(pieces, "HmacSHA256");

    }
    public void verifySignature(String[] pieces, String algorithm) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Mac hmac = Mac.getInstance(algorithm);
        hmac.init(new SecretKeySpec(bsecret, algorithm));
        byte[] sig = hmac.doFinal(new StringBuilder(pieces[0]).append(".").append(pieces[1]).toString().getBytes());
        System.out.println(sig+"\n"+decoder.decodeBase64(pieces[2]));
        if (!MessageDigest.isEqual(sig, decoder.decodeBase64(pieces[2]))) {
            throw new SignatureException("signature verification failed");
        }
    }
}

但我总是得到“签名验证失败”。

线程“main”中的异常java.security.SignatureException:签名验证失败

猜猜我错过了什么。我不知道从哪里开始。 我已使用http://kjur.github.io/jsjws/tool_jwt.html检查了有效负载。它在那里工作得很好。所以关键和信息是正确的。

1 个答案:

答案 0 :(得分:1)

如果您使用new byte[] {10, 10, -61, -102};作为bsecret的值,则MAC会为您验证。

jsjws tool以一种我不太懂的方式将用于共享密钥的字符串转换为字节。类似于十六进制解码的东西,但它会接受像“anandan”这样的非十六进制,并仍然签署JWT。我不确定为什么,但上面提到的字节是它将“anandan”转换成的内容,但这就是发生的事情。