Как видно из названия, у меня есть файл .p12, необходимый для доступа к учетной записи google service. Чтобы получить учетные данные для подключения к api, появится поле .setServiceAccountPrivateKey(PrivateKey privateKey). Итак, какой самый простой способ сделать это? У меня есть папка с ресурсами, которая находится в моем пути к классам, поэтому, если я добавлю там файл p12, я могу получить ресурс из getClass(). GetResource() как входной поток или URL-адрес. Я пробовал метод URL, но он не работает (я получаю ошибку "URI не является иерархической", пытаясь создать объект File из URL.toURI()).
Получение объекта PrivateKey из файла .p12 в Java
Ответ 1
Вы можете загрузить файл .p12 с помощью метода ClassLoader.getResourceAsStream(String)
, загрузить его в KeyStore и получить ключ от 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)
загружает ресурсы из любого местоположения, если они уже находятся в пути к классам, нет необходимости указывать путь к файлу.
keyAlias
- это имя записи в вашем файле p12, которая соответствует закрытому ключу. Файлы PKCS12 могут содержать несколько записей, поэтому вам нужно каким-то образом указать, к какой записи вы хотите получить доступ. Псевдоним, как это достигается.
Если вы не знаете, что такое псевдоним для вашего закрытого ключа, вы можете использовать утилиту keytool
из командной строки, чтобы отобразить содержимое вашего файла p12. Этот инструмент включен во все установки JRE и JDK.
keytool -list -keystore keyFile.p12 -storepass password -storetype PKCS12
Выход
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
Ответ 2
Я думаю, что проще сразу вызвать Google SecurityUtils, например:
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), this.getClass().getResourceAsStream("keyFile.p12"), "notasecret", "privatekey", "notasecret")
Это однострочное, и вам не нужно беспокоиться об псевдониме.
Ответ 3
Если вы получаете null
из getKey()
(например, используете BouncyCastle
в качестве поставщика), вы должны найти последний элемент keyAlias
:
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);
Ответ 4
Вышеуказанные предложения не помогли мне. Затем я попробовал один из http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm, и он сработал. Скопируйте его ниже
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);
}
}
}