Подтвердить что ты не робот

Получение объекта PrivateKey из файла .p12 в Java

Как видно из названия, у меня есть файл .p12, необходимый для доступа к учетной записи google service. Чтобы получить учетные данные для подключения к api, появится поле .setServiceAccountPrivateKey(PrivateKey privateKey). Итак, какой самый простой способ сделать это? У меня есть папка с ресурсами, которая находится в моем пути к классам, поэтому, если я добавлю там файл p12, я могу получить ресурс из getClass(). GetResource() как входной поток или URL-адрес. Я пробовал метод URL, но он не работает (я получаю ошибку "URI не является иерархической", пытаясь создать объект File из URL.toURI()).

4b9b3361

Ответ 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);
    }
  }
}