30

正如标题所示,我有谷歌服务帐户 api 访问所需的 .p12 文件。为了获得连接到 api 的凭据,有一个字段 .setServiceAccountPrivateKey(PrivateKey privateKey)。那么,我能做到这一点的最简单方法是什么?我的类路径中有一个资源文件夹,所以如果我在其中添加 p12 文件,我可以从 getClass().getResource() 作为 inputStream 或 URL 获取资源。我尝试了 URL 方法,但它不起作用(尝试从 URL.toURI() 创建文件对象时出现“URI 不是分层”错误)。

4

4 回答 4

60

您可以使用该方法加载您的 .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
于 2013-09-04T19:13:45.170 回答
9

我认为直接调用谷歌的 SecurityUtils 更容易,例如:

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

它是单行的,您不必担心混叠。

于 2014-07-24T22:32:12.937 回答
6

如果您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);
于 2014-06-06T12:24:18.297 回答
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);
    }
  }
}
于 2017-01-31T09:53:36.310 回答