1. 概述

管理私钥是许多应用安全的关键环节。Java 密钥库(JKS)是存储加密密钥和证书的常用格式。本文将介绍两种从密钥库中列出和导出私钥的方法:命令行操作和 Java 编程实现。

2. 使用命令行操作

首先通过 JDK 提供的 keytool 工具列出密钥库中的所有条目(包括私钥、证书和别名):

keytool -list -keystore mykeystore.jks -storepass mypassword

⚠️ 参数说明:

  • mykeystore.jks:密钥库文件名
  • mypassword:密钥库密码

执行后输出类似如下内容:

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: privatekey1
Creation date: May 29, 2024
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Example, OU=Development, O=Company, L=City, ST=State, C=Country
...

Alias name: privatekey2
Creation date: May 29, 2024
...

接下来将目标私钥(通过 -srcalias 指定)从 JKS 文件导出为 PKCS12 格式:

keytool -importkeystore -srckeystore mykeystore.jks -destkeystore mykeystore.p12 -srcstoretype JKS -deststoretype PKCS12 
  -srcalias privatekey1 -srcstorepass mypassword -deststorepass mypassword

然后使用 openssl 从 PKCS12 密钥库提取私钥:

openssl pkcs12 -in mykeystore.p12 -nocerts -nodes -out privatekey.pem -passin pass:mypassword

✅ 关键参数:

  • -nocerts:不输出证书
  • -nodes:不加密私钥

最后将 PEM 格式私钥转换为 PKCS8 格式:

openssl pkcs8 -in privatekey.pem -topk8 -nocrypt -out privatekey-pkcs8.pem

✅ 转换参数:

  • -topk8:转换为 PKCS8 格式
  • -nocrypt:不加密输出

最终得到的私钥文件内容如下:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCymad+US28aEBs
hj5nPJyiPotlyafiJSIKwbOu1rHcUYQukDxzRiKgp/j5dzneWhd7BUKDGLUNPL21
...
k7x6oTwzOTJsWsED69ZOC1E=
-----END PRIVATE KEY-----

3. 使用 Java 实现

通过 Java 代码读取密钥库中的私钥更灵活,核心步骤如下:

try (InputStream is = new FileInputStream("mykeystore.jks")) {
    // 加载密钥库
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    char[] passwordCharArr = "mypassword".toCharArray();
    keystore.load(is, passwordCharArr);

    // 遍历所有别名
    for (String alias : Collections.list(keystore.aliases())) {
        if (keystore.isKeyEntry(alias)) {
            // 获取私钥条目
            KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry(
              alias, new KeyStore.PasswordProtection(passwordCharArr));
            PrivateKey privateKey = pkEntry.getPrivateKey();
            
            // 输出私钥(PKCS8格式)
            System.out.println("Alias: " + alias);
            System.out.println("-----BEGIN PRIVATE KEY-----");
            System.out.println(Base64.getMimeEncoder(64, "\n".getBytes())
              .encodeToString(privateKey.getEncoded()));
            System.out.println("-----END PRIVATE KEY-----");
        }
    }
}

✅ 代码要点:

  1. 使用 try-with-resources 自动关闭输入流
  2. 通过 isKeyEntry() 过滤私钥条目
  3. Base64.getMimeEncoder() 格式化输出

4. 总结

对比两种方法:

  • 命令行方案:简单粗暴,适合快速操作
  • Java 方案:更灵活,适合程序化处理密钥库内容

❌ 踩坑提醒:实际操作时注意密钥库密码的安全性,避免硬编码在代码中

完整示例代码可在 GitHub 获取。


原始标题:List Private Keys From a Keystore | Baeldung