Skip to content

Instantly share code, notes, and snippets.

@joona
Created March 13, 2015 12:45
Show Gist options
  • Save joona/810babe22aefe906582b to your computer and use it in GitHub Desktop.
Save joona/810babe22aefe906582b to your computer and use it in GitHub Desktop.
Google service account JSON key to Google OAuth2 access token request
package io.inbot;
import com.github.jsonj.JsonObject;
import com.github.jsonj.tools.JsonParser;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.util.Base64;
import java.util.Scanner;
import static com.github.jsonj.tools.JsonBuilder.field;
import static com.github.jsonj.tools.JsonBuilder.object;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, InvalidKeyException, IOException {
System.out.println("Reading JSON key from: " + args[0]);
String content = new Scanner(new File(args[0])).useDelimiter("\\Z").next();
JsonParser jsonParser = new JsonParser();
JsonObject jsonKey = jsonParser.parseObject(content);
JsonObject headers = object(
field("alg", "RS256"),
field("typ", "JWT")
);
JsonObject claims = object(
field("iss", jsonKey.getString("client_email")),
field("scope", "https://www.googleapis.com/auth/devstorage.full_control"),
field("aud", "https://www.googleapis.com/oauth2/v3/token"),
field("exp", Instant.now().plusSeconds(60 * 55).getEpochSecond()),
field("iat", Instant.now().getEpochSecond())
);
String encodedHeaders = new String(Base64.getUrlEncoder().encode(headers.toString().getBytes()), Charset.defaultCharset());
String encodedClaims = new String(Base64.getUrlEncoder().encode(claims.toString().getBytes()), Charset.defaultCharset());
String payload = encodedHeaders + "." + encodedClaims;
System.out.println("Encoded headers: " + encodedHeaders);
System.out.println("Encoded claims: " + encodedClaims);
Signature sig = Signature.getInstance("SHA256withRSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String privKeyString = jsonKey.getString("private_key");
String privKeyPEM = privKeyString.replace("-----BEGIN PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
privKeyPEM = privKeyPEM.replace("\n", "");
System.out.println(privKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privKeyPEM));
PrivateKey privateKey = keyFactory.generatePrivate(privKeySpec);
System.out.println(privateKey);
sig.initSign(privateKey);
sig.update(payload.getBytes(Charset.defaultCharset()));
String signature = new String(Base64.getUrlEncoder().encode(sig.sign()), Charset.defaultCharset());
System.out.println("Signature: " + signature);
System.out.println("JWT:");
System.out.println(payload + "." + signature);
System.out.println("curl -XPOST -d \"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + payload + "." + signature + "\" https://www.googleapis.com/oauth2/v3/token");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment