I have a signed JWT String that i get from the server. I do not know the key or rather I don't want to put the key on the client/device.
When using this site with my token: https://jwt.io/ I get the desired result it tells me the Header and payload information.
I cannot find a library on android that does what this website does and i have tried all of them that i could find. The most recognized one to use is: https://github.com/jwtk/jjwt
But this gives me an exception that i cannot parse a signed token which as proven by the other website above is false. another resource i have used is: https://bitbucket.org/b_c/jose4j/wiki/Home
This one at least gave me the header information which is the furthest i have been able to get.
To give context why it is the way it is, the payload contains an expiration time and on the device when the token is about to expire i should prompt the user to re enter their credentials to get a new token. Now this might seem like a security threat because a hacker could manipulate the token on the device, but the server checks the token to make sure it is authentic which is why i do not want the key on the device because this can be mined by a hacker, and make the entire application vulnerable.
Well the answer was pretty simple although in my opinion should be in the framework. But a simple non signed JWT still has the 2 required periods in it but there is nothing after the last one, so i split my JWT on the periods and combined the first and second one with periods and put a period at the end.
String[] splitToken = result.Value.Content.AuthorizationJWTToken.split("\\.");
Jwt parsedToken = Jwts.parser().parse(splitToken[0] + "." + splitToken[1] + ".");
This was usings the https://github.com/jwtk/jjwt library.
You can use jose4j's JWT consumer to do parsing only and not check the claims or signature. Something like the following will parse the token and compare the expiration time to the current time to see if it's expired.
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);
}
If you wanna parse signatured text without using signature :
1- add below dependency :
//JWT
compile 'io.jsonwebtoken:jjwt:0.7.0'
2 - Add below imports :
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
3- Use below code block :
//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.
*/