![](/img/trans.png)
[英]How do I import the private and public keys (pvk,spc) and certificates (cer) into the keystore?
[英]How do I list / export private keys from a keystore?
如何从密钥库中列出和导出私钥?
您可以使用Java6和OpenSSL从密钥库中提取私钥。 这完全取决于Java和OpenSSL都支持PKCS#12格式的密钥库。 要进行提取,首先使用keytool
转换为标准格式。 确保对两个文件使用相同的密码(私钥密码,而不是密钥库密码),否则稍后您将在第二步中遇到奇怪的故障。
keytool -importkeystore -srckeystore keystore.jks \
-destkeystore intermediate.p12 -deststoretype PKCS12
接下来,使用OpenSSL对PEM进行提取:
openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes
您应该能够轻松地处理该PEM文件; 它是纯文本,带有编码的未加密私钥和证书(以非常明显的格式)。
执行此操作时,请注意保持创建的文件安全。 它们包含秘密凭证。 如果你没有正确地保护它们,没有什么会警告你。 保护它们的最简单方法是在一个目录中完成所有这些操作,该目录对用户以外的任何人都没有任何访问权限。 永远不要将密码放在命令行或环境变量中; 这对其他用户来说太容易了。
最初来自Example Depot的一部分代码,用于列出密钥库中的所有别名:
// Load input stream into keystore
keystore.load(is, password.toCharArray());
// List the aliases
Enumeration aliases = keystore.aliases();
for (; aliases.hasMoreElements(); ) {
String alias = (String)aliases.nextElement();
// Does alias refer to a private key?
boolean b = keystore.isKeyEntry(alias);
// Does alias refer to a trusted certificate?
b = keystore.isCertificateEntry(alias);
}
几个月前, Sun论坛上出现了私钥, u:turingcompleter提出了一个DumpPrivateKey类来拼接你的应用程序。
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import sun.misc.BASE64Encoder;
public class DumpPrivateKey {
/**
* Provides the missing functionality of keytool
* that Apache needs for SSLCertificateKeyFile.
*
* @param args <ul>
* <li> [0] Keystore filename.
* <li> [1] Keystore password.
* <li> [2] alias
* </ul>
*/
static public void main(String[] args)
throws Exception {
if(args.length < 3) {
throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
}
final String keystoreName = args[0];
final String keystorePassword = args[1];
final String alias = args[2];
final String keyPassword = getKeyPassword(args,keystorePassword);
KeyStore ks = KeyStore.getInstance("jks");
ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
Key key = ks.getKey(alias, keyPassword.toCharArray());
String b64 = new BASE64Encoder().encode(key.getEncoded());
System.out.println("-----BEGIN PRIVATE KEY-----");
System.out.println(b64);
System.out.println("-----END PRIVATE KEY-----");
}
private static String getKeyPassword(final String[] args, final String keystorePassword)
{
String keyPassword = keystorePassword; // default case
if(args.length == 4) {
keyPassword = args[3];
}
return keyPassword;
}
}
注意:这个使用Sun包, 这是一个“坏事” 。
如果你可以下载apache commons代码 ,这里有一个版本,它会在没有警告的情况下编译:
javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java
并将给出相同的结果:
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
//import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;
public class DumpPrivateKey {
/**
* Provides the missing functionality of keytool
* that Apache needs for SSLCertificateKeyFile.
*
* @param args <ul>
* <li> [0] Keystore filename.
* <li> [1] Keystore password.
* <li> [2] alias
* </ul>
*/
static public void main(String[] args)
throws Exception {
if(args.length < 3) {
throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
}
final String keystoreName = args[0];
final String keystorePassword = args[1];
final String alias = args[2];
final String keyPassword = getKeyPassword(args,keystorePassword);
KeyStore ks = KeyStore.getInstance("jks");
ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
Key key = ks.getKey(alias, keyPassword.toCharArray());
//String b64 = new BASE64Encoder().encode(key.getEncoded());
String b64 = new String(Base64.encodeBase64(key.getEncoded(),true));
System.out.println("-----BEGIN PRIVATE KEY-----");
System.out.println(b64);
System.out.println("-----END PRIVATE KEY-----");
}
private static String getKeyPassword(final String[] args, final String keystorePassword)
{
String keyPassword = keystorePassword; // default case
if(args.length == 4) {
keyPassword = args[3];
}
return keyPassword;
}
}
您可以像这样使用它:
java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat
如果您不需要以编程方式执行此操作,但只想管理密钥,那么我已经使用IBM的免费KeyMan工具了很长时间。 非常适合将私钥导出到PFX文件(然后您可以轻松地使用OpenSSL来操作它,提取它,更改pwds等)。
选择密钥库,选择私钥条目,然后选择文件 - >保存到pkcs12文件(通常为* .pfx)。 然后,您可以使用以下内容查看内容
$ openssl pkcs12 -in mykeyfile.pfx -info
以下是Groovy中上述代码的较短版本。 还有内置的base64编码:
import java.security.Key
import java.security.KeyStore
if (args.length < 3)
throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>')
def keystoreName = args[0]
def keystoreFormat = args[1]
def keystorePassword = args[2]
def alias = args[3]
def keyPassword = args[4]
def keystore = KeyStore.getInstance(keystoreFormat)
keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray())
def key = keystore.getKey(alias, keyPassword.toCharArray())
println "-----BEGIN PRIVATE KEY-----"
println key.getEncoded().encodeBase64()
println "-----END PRIVATE KEY-----"
这个问题出现在stackexchange安全性上,其中一个建议是使用Keystore explorer
刚试过它,它的效果非常好,我强烈推荐它。
对于android开发,要将在eclipse ADT中创建的密钥库转换为SignApk.jar中使用的公钥和私钥:
导出私钥:
keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der
openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem
编辑private.rsa.pem并将“----- BEGIN PRIVATE KEY -----”留给“----- END PRIVATE KEY -----”段落,然后:
openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der
出口公钥:
keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der
标志apk:
java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk
首先,要小心! 您的所有安全性取决于私人密钥的 私密性。 Keytool没有内置密钥导出以避免意外泄露此敏感材料,因此您可能需要考虑一些额外的保护措施,以保护您的导出密钥。
下面是一些简单的代码,它为您提供OpenSSL可以使用的未加密的PKCS#8 PrivateKeyInfo(请参阅其pkcs8实用程序的-nocrypt
选项):
KeyStore keys = ...
char[] password = ...
Enumeration<String> aliases = keys.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (!keys.isKeyEntry(alias))
continue;
Key key = keys.getKey(alias, password);
if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
/* Most PrivateKeys use this format, but check for safety. */
try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
os.write(key.getEncoded());
os.flush();
}
}
}
如果您需要其他格式,可以使用KeyFactory为不同类型的密钥获取透明密钥规范。 然后,您可以获得RSA私钥的私有指数,并以所需格式输出。 这将成为后续问题的一个好主题。
另一个很棒的工具是KeyStore Explorer: http : //keystore-explorer.sourceforge.net/
JXplorer是另一种不那么传统但可以说更简单的方法。 尽管此工具旨在浏览LDAP目录,但它具有易于使用的GUI来操作密钥库。 GUI上的一个这样的功能可以从JKS密钥库导出私钥。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.