Android JWT在签名时解析有效负载/声明

时间:2016-01-25 17:44:23

标签: java android security jwt

我从服务器获得了一个签名的JWT字符串。我不知道密钥,或者我不想把钥匙放在客户端/设备上。

将此网站与我的令牌一起使用时:https://jwt.io/我得到了所需的结果,它告诉我标题和有效负载信息。

我无法在Android上找到一个能够完成本网站功能的库,我已经尝试了所有我能找到的库。最受认可的是:https://github.com/jwtk/jjwt

但这给了我一个例外,我无法解析一个签名的令牌,上面的其他网站证明这是假的。我使用的另一个资源是:https://bitbucket.org/b_c/jose4j/wiki/Home

这个至少给了我头条信息,这是我能够得到的最远的信息。

为了给出上下文的原因,有效负载包含到期时间,并且当令牌即将到期时,设备上应该提示用户重新输入其凭据以获取新令牌。现在这似乎是一个安全威胁,因为黑客可以操纵设备上的令牌,但服务器检查令牌以确保它是真实的,这就是为什么我不想要设备上的密钥,因为这可以通过黑客,并使整个应用程序易受攻击。

4 个答案:

答案 0 :(得分:3)

答案很简单,但我认为应该在框架中。但是一个简单的非签名JWT仍然有2个必需的句号,但是在最后一个之后没有任何内容,所以我将JWT分成句点,并将第一个和第二个与句点合并,并在句末结束。

String[] splitToken = result.Value.Content.AuthorizationJWTToken.split("\\.");
Jwt parsedToken = Jwts.parser().parse(splitToken[0] + "." + splitToken[1] + ".");

这是使用https://github.com/jwtk/jjwt库。

答案 1 :(得分:2)

如果您想在不使用签名的情况下解析签名文本:

1-添加以下依赖:

//JWT
compile 'io.jsonwebtoken:jjwt:0.7.0'

2 - 添加以下导入:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;

3-使用以下代码块:

//ref : https://github.com/jwtk/jjwt/issues/135
//you can put your signatured text instead of jws variable.
String jws = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
int i = jws.lastIndexOf('.')
String withoutSignature = jws.substring(0, i+1);
Jwt<Header,Claims> untrusted = Jwts.parser().parseClaimsJwt(withoutSignature);
/*untrusted.getBody().getSubject();
  untrusted.getBody().getExpiration();
  etc.
*/

答案 2 :(得分:1)

您可以使用jose4j's JWT consumer仅进行解析,而不检查声明或签名。以下内容将解析令牌并将到期时间与当前时间进行比较,以查看它是否已过期。

String jwt = "eyJhbGciOiJIUzI1NiJ9" +
        ".eyJzdWIiOiIxMjM0NTY3ODkwIiwiZXhwIjoxNDUzODE0NjA0LCJuYW1lIjoiSm9obiBEb2UifQ" +
        ".IXcDDLXEpGN9Po5C-Mz88jUCNYrHxu6TVJLavf0NgT8";

JwtConsumer consumer = new JwtConsumerBuilder()
        .setSkipAllValidators()
        .setDisableRequireSignature()
        .setSkipSignatureVerification()
        .build();
JwtClaims claims = consumer.processToClaims(jwt);
NumericDate expirationTime = claims.getExpirationTime();

if (NumericDate.now().isAfter(expirationTime))
{
    System.out.println("Token expired at " + expirationTime);
}
else
{
    System.out.println("Token is still good until " + expirationTime);
}

答案 3 :(得分:1)

Jwt的

parseClaimsJwt() 方法需要签名。因此,正确的方法是:

String jws = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
int i = jws.lastIndexOf('.')
String withoutSignature = jws.substring(0, i+1);

Claims claims = (Claims) = Jwts.parser().parse(withoutSignature).getBody();