As the title suggests, I have .p12 file required for google service account api access. In order to get the credential to connect to the api, there's a field .setServiceAccountPrivateKey(PrivateKey privateKey). So, what's the easiest way in which I can do this? I have a resources folder which is in my classpath so if I add the p12 file there, I can get the resource from getClass().getResource() as either an inputStream or a URL. I've tried the URL method but it doesn't work (I get a "URI is not hierarchical" error trying to create a File object from URL.toURI()).
4 Answers
You can load your .p12 file using the ClassLoader.getResourceAsStream(String)
method, load it to a KeyStore and them get the key from the KeyStore.
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(this.getClass().getClassLoader().getResourceAsStream("keyFile.p12"), p12Password.toCharArray());
PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, p12Password.toCharArray());
ClassLoader.getResourceAsStream(String)
loads resources from any location provided they're already on the classpath, there's no need to specify a path to the file.
keyAlias
is the name of the entry in your p12 file that corresponds to the private key. PKCS12 files can contain multiple entries, so you need some way to indicate which entry you want to access. The alias is how this is achieved.
If you're not sure what the alias for your private key is, you can use the keytool
utility from the command line to list the contents of your p12 file. This tool is included with all JRE and JDK installations.
keytool -list -keystore keyFile.p12 -storepass password -storetype PKCS12
Output
Keystore type: PKCS12
Keystore provider: SunJSSE
Your keystore contains 1 entry
yourKeyAlias, Sep 4, 2013, PrivateKeyEntry,
Certificate fingerprint (MD5): 48:A8:C4:12:8E:4A:8A:AD:58:81:26:90:E7:3D:C8:04

- 7,205
- 5
- 36
- 40
-
Not to familiar with this encryption method... what is keyAlias? – gratsby Sep 04 '13 at 19:25
-
Added info on how to list the contents of your keystore to find the alias. – Syon Sep 04 '13 at 19:37
-
@Syon Would that possible to create keystore from its content, rather from a java.io.File? – DarRay Apr 29 '14 at 05:29
-
I'm not totally sure what you mean by "from it's content". The KeyStore class has various ways to load a key in to it. You could do `keystore.load(new ByteArrayInputStream(someByteArray))`, or you could use one of the `SetKeyEntry` methods. – Syon Apr 29 '14 at 11:53
-
Where is the 'p12Password.toCharArray()' coming from? – Tom Jul 14 '15 at 09:48
-
@TomWilkins p12Password is the password provided by google. store the password in string and convert it into char Array. Hint "Google use same public key password". – Sagar Rout Dec 14 '15 at 16:01
I think it's easier to call Google's SecurityUtils directly, e.g.:
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), this.getClass().getResourceAsStream("keyFile.p12"), "notasecret", "privatekey", "notasecret")
It's one-line and you don't have to worry about aliasing.

- 179
- 2
- 10
-
2Thanks for putting the password right in there too, I was worried I'd forgotten it. – dhakim Aug 12 '14 at 18:18
-
@Robert Watts So in this call you use "privatekey" as the alias. Is that because privateKey is the default alias for pkcs12 keys? I searched but could not find any documentation on this. I ran the keytool and my alias is in fact "privatekey" but I'd like to be sure it always will be for new keys. – Usman Mutawakil Sep 11 '16 at 08:55
-
@UsmanMutawakil I don't believe there's any standard default alias for the pkcs12 file format. Keytool may be defaulting to that alias, and perhaps other tools/programs do too, but it's not inherently in the file format. – Vivek Chavda Oct 31 '16 at 20:15
-
1
-
2I do find it funny that a class called SecurityUtils would accept a password as a string. – Syon Sep 28 '17 at 14:36
-
If you get null
from getKey()
(eg. you are using BouncyCastle
as a provider) you should find the last keyAlias
element:
KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
keystore.load(this.getClass().getClassLoader().getResourceAsStream("keyFile.p12"), p12Password.toCharArray());
Enumeration aliases = keystore.aliases();
String keyAlias = "";
while (aliases.hasMoreElements()) {
keyAlias = (String) aliases.nextElement();
}
PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, pass);

- 463
- 4
- 14
-
This is what helped me in the end. My keystore had a weird alias that getkey was always returning null. Iterating using the above method solved the issue. – Nikhil Kumar Feb 12 '20 at 07:17
-
This helped me so much. Thanks. `keytool` show that I have an alias named "1" (the default one when created with `openssl`. Not sure it is `int` or `string`). However `keystore.aliases()` return a long weird string for that alias. – Phạm Tuấn Anh Dec 15 '20 at 04:23
The above suggestions did not work for me. Then I tried the one at http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm and it worked. Copy pasting it below
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
public class Main {
public static void main(String[] argv) throws Exception {
FileInputStream is = new FileInputStream("your.keystore");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, "my-keystore-password".toCharArray());
String alias = "myalias";
Key key = keystore.getKey(alias, "password".toCharArray());
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
new KeyPair(publicKey, (PrivateKey) key);
}
}
}

- 1,236
- 11
- 9