1 /** 2 * Copyright 2021 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 // [START java-jwt-verify-example] 15 package jwt; 16 17 import static java.nio.charset.StandardCharsets.UTF_8; 18 19 import com.google.crypto.tink.KeysetHandle; 20 import com.google.crypto.tink.RegistryConfiguration; 21 import com.google.crypto.tink.jwt.JwkSetConverter; 22 import com.google.crypto.tink.jwt.JwtPublicKeyVerify; 23 import com.google.crypto.tink.jwt.JwtSignatureConfig; 24 import com.google.crypto.tink.jwt.JwtValidator; 25 import com.google.crypto.tink.jwt.VerifiedJwt; 26 import java.nio.file.Files; 27 import java.nio.file.Path; 28 import java.nio.file.Paths; 29 import java.time.Instant; 30 import java.time.temporal.ChronoUnit; 31 import java.util.List; 32 33 /** 34 * A command-line utility for verifying JSON Web Tokens (JWTs). 35 * 36 * <p>It requires the following arguments: 37 * 38 * <ul> 39 * <li>public-jwkset-file: Name of the input file containing the public keyset in JWK set format. 40 * <li>audience: The audience claim to be used in the token 41 * <li>token-file: name of the input file containing the signed JWT. 42 */ 43 public final class JwtVerify { main(String[] args)44 public static void main(String[] args) throws Exception { 45 if (args.length != 3) { 46 System.err.printf("Expected 3 parameters, got %d\n", args.length); 47 System.err.println( 48 "Usage: java JwtVerify public-jwk-set-file audience token-file"); 49 System.exit(1); 50 } 51 52 Path publicJwkSetFile = Paths.get(args[0]); 53 String audience = args[1]; 54 Path tokenFile = Paths.get(args[2]); 55 56 // Register all JWT signature key types with the Tink runtime. 57 JwtSignatureConfig.register(); 58 59 // Read the public keyset in JWK set format into a KeysetHandle. 60 KeysetHandle publicKeysetHandle = 61 JwkSetConverter.toPublicKeysetHandle( 62 new String(Files.readAllBytes(publicJwkSetFile), UTF_8)); 63 64 List<String> lines = Files.readAllLines(tokenFile, UTF_8); 65 if (lines.size() != 1) { 66 System.err.printf("The signature file should contain only one line, got %d", lines.size()); 67 System.exit(1); 68 } 69 String signedToken = lines.get(0).trim(); 70 71 // Get the primitive. 72 JwtPublicKeyVerify verifier = 73 publicKeysetHandle.getPrimitive(RegistryConfiguration.get(), JwtPublicKeyVerify.class); 74 75 // Use the primitive to verify a token. 76 JwtValidator validator = JwtValidator.newBuilder().expectAudience(audience).build(); 77 VerifiedJwt verifiedJwt = verifier.verifyAndDecode(signedToken, validator); 78 long seconds = ChronoUnit.SECONDS.between(Instant.now(), verifiedJwt.getExpiration()); 79 System.out.println("Token is valid and expires in " + seconds + " seconds."); 80 } 81 JwtVerify()82 private JwtVerify() {} 83 } 84 // [END java-jwt-verify-example] 85