Unable to convert .jks to .pkcs12: excess private key

谁说我不能喝 提交于 2019-12-06 13:15:37

Good work finding that JS. (FYI Stack only does one @ per comment -- fortunately I saw this in recently-modified.)

From that we can now see your privatekey has attributes in the PKCS8 (a legal but very rarely used feature) which on rechecking I see standard JCE does not support (there's a comment in decode but not in parseKey). It appears BouncyCastle does -- but bcprov doesn't do JKS.

I suggest you proceed with OpenSSL here since that's what you want to end up with anyway. You can definitely convert certificate file from binary/DER to PEM with:

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

I'm pretty sure you can convert the key file to PEM with:

 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

but if that doesn't work you can do it by hand:

(echo "-----BEGIN PRIVATE KEY-----"; openssl base64 <key; echo "-----END PRIVATE KEY-----") >key.pem 

and then you should be able to feed the PEM files to openssl pkcs12 -export -engine dstu to create a PKCS12.

Altternatively, since StackOverflow is supposed to be about programming, I think it will work if you use the BC provider to read the key and write a PKCS12, something like:

KeyFactory kf = KeyFactory.getInstance ("DSTU4145", "BC");
PrivateKey key = kf.generatePrivate (new PKCS8EncodedKeySpec (Files.readAllBytes("key")));
CertificateFactory cf = CertificateFactory.getInstance ("X.509", "BC");
// not sure we need the BC implementation for the certs, but can't hurt 
Certificate[] certs = new Certificate[4];
for( int i = 0; i < 4; i++ ){
  certs[i] = cf.generateCertificate (new FileInputStream ("cert"+i));
  // or "cert"+i+".pem" -- CertificateFactory can read either DER or PEM
}
// or concatenate the cert PEM files into one and do
Certificate[] certs = cf.generateCertificates (new FileInputStream ("certs.pem")).toArray(new Certificate[0]);
// better to close the stream(s) when done like below but for input isn't vital

KeyStore ks = KeyStore.getInstance ("PKCS12", "BC"); ks.load(null); 
char[] pw = "password".toCharArray(); // or preferably better value
ks.setKeyEntry("mykey", pkey, pw, certs);
try(OutputStream os = new FileOutputStream("result")){ ks.store(os, pw); }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!