【问题标题】:How do i read the private key in java from a pfx certificate如何从 pfx 证书中读取 java 中的私钥
【发布时间】:2013-01-09 13:00:39
【问题描述】:

我正在尝试读取 java 中的私钥。我了解到,为了做到这一点,我必须从 pfx 格式的完整证书中提取私钥。 我尝试了下面的 open ssl 命令将 pfx 转换为 pem 然后再转换为 pk8 ,但是当我尝试在 java 中读取密钥时,它说无效的密钥格式

将 pfx 转换为 pem

      openssl pkcs12 -in C:\Documents\xbox-token\conversion\xbox
  token-FullCert.pfx -nocerts -out C:\Documents\xbox-token\conversion\xboxkey.pem

删除密码保护

openssl rsa -in C:\Documents\xbox-token\conversion\xboxkey.pem  -out C:\Documents\xbox-token\conversion\xboxkey.pem

将 pem 转换为 pk8

openssl pkcs8 -topk8 -in C:\Documents\xbox-token\conversion\xboxkey.pem -out C:\Documents\xbox-token\conversion\xboxprv.pk8

在java代码中

  byte[] encodedPrivateKey=null;
    File privateKeyFile = new File("C:/Documents/xbox-token/conversion/xboxprv.pk8");
    FileInputStream inputStreamPrivateKey = null;
    try {
        inputStreamPrivateKey = new FileInputStream(privateKeyFile);
          encodedPrivateKey = new byte[(int)privateKeyFile.length()];
            inputStreamPrivateKey.read(encodedPrivateKey);
            inputStreamPrivateKey.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // Create the private key.
    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
    System.out.println(encodedPrivateKey);
    System.out.println(privateKeySpec);
    RSAPrivateKey privateKey = null;
    try {
        privateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

我得到一个 java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format

谁能帮忙

【问题讨论】:

标签: java security openssl private-key pem


【解决方案1】:

我认为诀窍是使用 openssl 做一些事情,然后让 keytool 完成所有实际工作。因此,使用 openssl 将您现有的证书和密钥转换为 PKCS12 文件。使用 openssl 你会有类似的东西。

openssl pkcs12 \
  -export -in cert.crt \
  -inkey cert.key \
  -certfile ica.crt \
  -name "yourKey" \
  -out cert.p12

然后魔术就是将 .p12 导入您的密钥库,就好像它是另一个密钥库。

$JAVA_HOME/bin/keytool \
  -importkeystore -deststorepass secret \
  -destkeypass secret -destkeystore $KEYSTORE \
  -srckeystore cert.p12 \
  -srcstoretype PKCS12 \
  -srcstorepass secret \
  -alias "yourKey"

您可以选择在 java 中使用它,但我希望完整的答案涉及以下内容。

import java.security.KeyStore;
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File("/your/keystore"));
trustStore.load(instream, "secret".toCharArray());

希望它有效!

【讨论】:

  • 但我确实需要它作为 p8 而不是 p12。我添加的程序只是其中的一部分。我需要 p8 格式,因为我需要使用密钥进行 saml 解密
【解决方案2】:

如果您没有为 OpenSSL 命令指定输出格式,您将获得一个 PEM 编码的文件。 Java 将期望 DER 编码。而不是你上次的 openssl 调用尝试:

openssl pkcs8 -topk8 -inform=PEM -outform=DER
              -in C:\Documents\xbox-token\conversion\xboxkey.pem 
              -out C:\Documents\xbox-token\conversion\xboxprv.pk8

“-inform”参数不应该是必需的(这似乎是默认值),但“-outform”可能是。

如果您想检查您的格式:PEM 文件是 ASCII(Base64 编码),DER 文件是二进制文件。如果您的文本编辑器喜欢它,Java 可能不会。

【讨论】:

  • 读取带有“--”行的pem内容并进行Base64解码。 java.util.Base64.getDecoder().decode(pemWithoutHyphenLines)
猜你喜欢
  • 2013-12-10
  • 2015-01-20
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 2016-11-03
  • 1970-01-01
  • 2011-05-29
相关资源
最近更新 更多