web-dev-qa-db-fra.com

Obtention d'un objet PrivateKey à partir d'un fichier .p12 dans Java

Comme le titre l'indique, j'ai un fichier .p12 requis pour l'accès à l'API du compte de service Google. Afin d'obtenir les informations d'identification pour se connecter à l'API, il existe un champ .setServiceAccountPrivateKey (PrivateKey privateKey). Alors, quelle est la façon la plus simple de le faire? J'ai un dossier de ressources qui se trouve dans mon chemin de classe, donc si j'y ajoute le fichier p12, je peux obtenir la ressource de getClass (). GetResource () en tant que InputStream ou URL. J'ai essayé la méthode URL mais cela ne fonctionne pas (j'obtiens une erreur "URI is not hierarchical" en essayant de créer un objet File à partir de URL.toURI ()).

28
gratsby

Vous pouvez charger votre fichier .p12 à l'aide de la méthode ClassLoader.getResourceAsStream(String), le charger dans un magasin de clés et les récupérer la clé dans le magasin de clés.

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) charge les ressources de n'importe quel emplacement à condition qu'elles soient déjà sur le chemin de classe, il n'est pas nécessaire de spécifier un chemin vers le fichier.

keyAlias est le nom de l'entrée dans votre fichier p12 qui correspond à la clé privée. Les fichiers PKCS12 peuvent contenir plusieurs entrées, vous avez donc besoin d'un moyen d'indiquer à quelle entrée vous souhaitez accéder. L'alias est de savoir comment cela est réalisé.

Si vous n'êtes pas sûr de l'alias de votre clé privée, vous pouvez utiliser l'utilitaire keytool depuis la ligne de commande pour répertorier le contenu de votre fichier p12. Cet outil est inclus avec toutes les installations JRE et JDK.

keytool -list -keystore keyFile.p12 -storepass password -storetype PKCS12

Production

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
49
Syon

Je pense qu'il est plus facile d'appeler directement les SecurityUtils de Google, par exemple:

PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), this.getClass().getResourceAsStream("keyFile.p12"), "notasecret", "privatekey", "notasecret")

C'est une ligne et vous n'avez pas à vous soucier de l'alias.

8
Robert Watts

Si vous obtenez null de getKey() (par exemple, vous utilisez BouncyCastle en tant que fournisseur), vous devriez trouver le dernier élément 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
Stocki

Les suggestions ci-dessus n'ont pas fonctionné pour moi. Ensuite, j'ai essayé celui à http://www.Java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm et cela a fonctionné. Copiez-le ci-dessous

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);
    }
  }
}
2
sdm