无法将.jks转换为.pkcs12:多余的私钥

时间:2017-12-28 20:58:18

标签: java ssl https keytool jks

2017年12月30日更新 - 4

我设法解压缩.jks文件并从中提取密钥和证书。为此,我编写了一个受signerbox2启发的小型nodejs程序,该程序使用.jks对数据进行签名。特别是,我使用jksreader npm包,现在只存在几天了!

我写的程序看起来像这样:

const fs = require('fs');
      jksreader = require('jksreader'),

      pathToFile = process.argv[2],
      password = process.argv[3],

      contents = fs.readFileSync(pathToFile),
      parsedContent = jksreader.parse(contents);

var   key = jksreader.decode(parsedContent.material[0].key, password);

fs.writeFileSync('key', key);

for (var i = 0; i < parsedContent.material[0].certs.length; i++) {
  var cert = parsedContent.material[0].certs[i];
  fs.writeFileSync('cert' + i, cert);
}

这个程序的调用如下:

node index.js /path/tp/my_key.jks my_password

输出看起来像一堆文件:

cert0
cert1
cert2
cert3
key

证书采用DER格式,可以像这样读取(注意-engine dstu参数):

openssl x509 -in cert2 -inform der -text -noout -engine dstu

但是,我无法弄清楚如何读取(或转换为PEM)密钥。我还在努力。 openssl asn1parse在密钥文件上运行良好。这是openssl asn1parse output。我不确定从哪里开始。

2017年12月28日更新 - 3

我安装了Keystore Explorer。它也无法提取私钥。它可以显示比keytool更多的信息。这里唯一奇怪的是,同一个证书有两个几乎相同的副本,以我的名字命名(以大写字母):

enter image description here

此处表明该条目符合DSTU-4145标准:

enter image description here

2017年12月28日更新 - 2

.jks中包含的密钥跟随或以某种方式与&#34; DSTU-4145签名方案&#34;相关联。 (算法)。这是乌克兰的政府标准。

我对签名方案几乎一无所知;例如,DSTU-4145可以在BouncyCastle specification page上播种。

也许我需要安装DSTU-4145算法,以便keytool知道如何提取私钥?

2017年12月28日更新 - 1

在Ubuntu的以下版本的java下执行此操作:

$ java -version
java version "1.7.0_151"
OpenJDK Runtime Environment (IcedTea 2.6.11) (7u151-2.6.11-2ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.151-b01, mixed mode)

同样不适用于macOS下的Java的以下版本:

java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

我提供了来自官方机构的.jks

我想将.jks文件转换为.pkcs12以与openssl一起使用以实际签名。相反,我得到一个错误。

这就是我正在做的事情:

$ keytool -importkeystore \
        -srckeystore my_keystore.jks \
        -destkeystore my_keystore.pkcs12 \
        -deststoretype pkcs12

Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Enter key password for <my_key>
keytool error: java.security.UnrecoverableKeyException: excess private key

但同时,可以列出密钥:

$ keytool -list -keystore my_key.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

my_key, Jan 18, 1970, PrivateKeyEntry,
Certificate fingerprint (SHA1): A1:B2:C3:D4:E5:F6:85:E4:2B:03:B9:68:FD:AE:9D:5B:24:CF:BF:FF

我做错了什么?

1 个答案:

答案 0 :(得分:2)

找到JS的好工作。 (FYI Stack只对每个评论做一个@ - 幸运的是我在最近修改时看到了这个。)

由此我们现在可以看到你的私钥在PKCS8中有属性(一个合法但很少使用的特性),在重新检查时我看到标准的JCE不支持(在{{1中有评论)但不在decode)。它似乎是BouncyCastle所做的 - 但是bcprov不会做JKS。

我建议您在这里继续使用OpenSSL,因为无论如何这都是您想要的结果。 您绝对可以使用以下命令将证书文件从binary / DER转换为PEM:

parseKey

我非常确定您可以使用以下命令将密钥文件转换为PEM:

 openssl x509 -in cert$i -inform der -out cert$i.pem -engine dstu 
 # or maybe pem$i or whatever names you find convenient

但如果这不起作用,你可以手工完成:

 openssl pkey -in key -inform der -out key.pem -engine dstu
 # or whatever name
 # output defaults to unencrypted but your input is already unencrypted so no loss

然后您应该能够将PEM文件提供给(echo "-----BEGIN PRIVATE KEY-----"; openssl base64 <key; echo "-----END PRIVATE KEY-----") >key.pem 以创建PKCS12。

或者,由于StackOverflow应该是关于编程的,我认为如果您使用BC提供程序读取密钥并编写PKCS12,它将起作用,如:

openssl pkcs12 -export -engine dstu