I am trying to get a bearer token using oAuth2 for connecting to a service account on GCP, I am following this documentation. To sign the JWT, the docs tell me to use "the private key obtained from the Google API Console".
Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google API Console.
I have the below code in Java to read that private key from a file
File privKeyFile = new File(keyPath);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream('myprivatekey.pem'));
byte[] privKeyBytes = new byte[8192]
bis.read(privKeyBytes);
bis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(privKeyBytes);
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
But this code is currently giving this exception
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException:
invalid key format at java_security_KeyFactory$generatePrivate$0.call(Unknown Source)
I tried converting private Key to PKCS#8 format as per this post but when I run this command
openssl pkcs8 -topk8 -inform PEM -outform DER -in myprivatekey.pem -nocrypt > pkcs8_key
I get this error
unable to load key
140735932699592:error:0906D06C:PEM routines:PEM_read_bio:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.3/libressl/crypto/pem/pem_lib.c:704:Expecting: ANY PRIVATE KEY
Was that not a valid RSA key which Google console provided? How can I read that key into my code so I can use it to sign the JWT?
The service account private key is PEM encoded RSA PKCS #8. The PKCS8EncodedKeySpec wants ASN.1 encoding without newlines, header, and tail.
The private key in your post appears valid and in the correct format.
WARNING: if that private key is from Google Cloud, immediately delete the key.
Use code similar to this:
public RSAPrivateKey readPrivateKey(File file) throws Exception {
String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
String privateKeyPEM = key
.replace("-----BEGIN PRIVATE KEY-----", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PRIVATE KEY-----", "");
byte[] encoded = Base64.decodeBase64(privateKeyPEM);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}