I'm receiving a JWT and would like to verify it's signature. It's not encrypted, is based64 encoded and is signed using HmacSha256. It is signed with a secret that I know.
I can't seem to find any example of how to verify the signature without using third part libraries listed on https://jwt.io/ i.e. java-jwt, jpose4j, etc....
Is it possible to do this?
What I have so far:
private boolean validateSignature( String header, String data, String signature, String secretKey ) throws Exception {
Base64 base64 = new Base64( true );
SecretKeySpec secret = new SecretKeySpec( secretKey.getBytes(), "HmacSHA256" );
Mac mac = Mac.getInstance( "HmacSHA256" );
mac.init( secret );
byte[] hmacDataBytes = mac.doFinal( data.getBytes( StandardCharsets.UTF_8.name()) );
String hmacData = new String( hmacDataBytes );
return hmacData.equals( signature ); // Compare signatures here...
}
Based on @pedrofb and @jps answers, here is solution:
private boolean validToken( String authToken, String key ) throws Exception {
String[] token = authToken.split( "\\." );
String header = token[0];
String payload = token[1];
String originalSignature = token[2];
SecretKeySpec secret = new SecretKeySpec( Base64.getDecoder().decode( key ), ALGORITM_HMACSHA256 );
Mac mac = Mac.getInstance( ALGORITM_HMACSHA256 );
mac.init( secret );
StringBuilder headerAndPayload = new StringBuilder( header ).append( "." ).append( payload );
byte[] signatureBytes = mac.doFinal( headerAndPayload.toString().getBytes( StandardCharsets.UTF_8.name() ) );
String calculatedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString( signatureBytes );
return calculatedSignature.equals( originalSignature );
}