从 Java 中的 .p12 文件获取 PrivateKey 对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18621508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a PrivateKey object from a .p12 file in Java
提问by gratsby
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()).
正如标题所暗示的,我有 .p12 文件,用于谷歌服务帐户 api 访问。为了获得连接到 api 的凭据,有一个字段 .setServiceAccountPrivateKey(PrivateKey privateKey)。那么,我可以做到这一点的最简单方法是什么?我有一个资源文件夹,它在我的类路径中,所以如果我在那里添加 p12 文件,我可以从 getClass().getResource() 获取资源作为 inputStream 或 URL。我已经尝试了 URL 方法,但它不起作用(尝试从 URL.toURI() 创建 File 对象时出现“URI 不是分层的”错误)。
采纳答案by Syon
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.
您可以使用该ClassLoader.getResourceAsStream(String)
方法加载 .p12 文件,将其加载到 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)
loads resources from any location provided they're already on the classpath, there's no need to specify a path to the file.
ClassLoader.getResourceAsStream(String)
从任何位置加载资源,只要它们已经在类路径上,就不需要指定文件的路径。
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.
keyAlias
是 p12 文件中与私钥对应的条目的名称。PKCS12 文件可以包含多个条目,因此您需要某种方式来指示要访问的条目。别名是如何实现的。
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
从命令行使用该实用程序来列出您的 p12 文件的内容。此工具包含在所有 JRE 和 JDK 安装中。
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
回答by Stocki
If you get null
from getKey()
(eg. you are using BouncyCastle
as a provider) you should find the last keyAlias
element:
如果您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);
回答by Robert Watts
I think it's easier to call Google's SecurityUtils directly, e.g.:
我认为直接调用 Google 的 SecurityUtils 更容易,例如:
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.
它是单行的,您不必担心混叠。
回答by sdm
The above suggestions did not work for me. Then I tried the one at http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htmand it worked. Copy pasting it below
以上建议对我不起作用。然后我在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);
}
}
}