I'm trying to convert a putty ppk file to pkcs12 for use by a Java keystore. I've Googled half the internet, and all approaches hinge around using openssl to convert the ppk file to pkcs12. After reading the ppk file with puttygen and converting the private key to openssh, this is what I try to execute:

openssl pkcs12 -export -inkey my.ppk -out new.p12

I have tried many variations, specifying name and all, but the openssl command hangs in the terminal or dos prompt. No error. Empty p12 file. Just blackness.

The PPK file can be read with puttygen. I have tried with and without passphrases. Exported to both private RSA and OpenSSH format.

Why is the PPK to PKCS12 conversion hanging?

  • What OS are you running it on; how did you install OpenSSL on it; and are you able to convert .pem files (such as openssl genrsa 1024 > test.key) to PKCS12 in the same way? – user1686 Jul 17 '19 at 5:48
  • I'm running windows; tried both the windows openssl and the embedded unix environment's openssl. Strange remains that I can read the ppk with puttygen and export the private key for this conversion. – tbeernot Jul 17 '19 at 6:50
  • Oh, the openssl genrsa 1024 > test.key works fine – tbeernot Jul 18 '19 at 6:12

Not sure what good the automatic zombie-tizing does, but for anyone who cares:

Why is the [attempted] PPK to PKCS12 conversion hanging?

openssl pkcs12 -export normally reads at least TWO things: a privatekey from -inkey, and a matching X.509-type certificate from -in or if that is not specified, as it was not in this case, from stdin (standard input). Often stdin will be redirected from a file which contains the cert or piped from a command that produces (could be retrieves, could be generates) it, but since those weren't done, openssl was waiting for the OP to type a certificate in PEM format on their terminal. This is because PKCS12 files normally contain privatekey(s) matched with the corresponding X.509 (or, effectively the same thing, PKIX) certificate(s).

That prompts a question OP did not ask

[where to get the certificate?]

SSH keys in general, and Putty keys in particular, do not have X.509 certificates. OpenSSH does have its own private kind of cert, almost completely unlike X.509, which is not interoperable with anybody else I know of including Putty.

The PKCS12 standard is extremely flexible -- some would say excessively -- and it is actually possible to have a PKCS12 file with only a privatekey and no matching certificate. OpenSSL can create this by adding -nocerts to the pkcs12 -export subcommand. (correction) However, this violates the stated requirements on the Java KeyStore API, and while in my testing the standard provider will read the file anyway, programs may or may not be able to use it.

Given a privatekey such as exported by Puttygen OpenSSL can create a 'self-signed' certificate for that key -- this is a dummy certificate that is not issued in the normal way, by a CA (Certificate Authority). There are actually two ways, both of which build on the subcommand req which nominally creates a CSR -- a Certificate Signing Request. In one step you can use openssl req -new -x509 -key privkeyfile -out certfile ... (where there are additional options for some of the data that goes in the certificate, like the subject name, the length of the validity period, and extensions) or in two steps you create a CSR but then 'approve' it yourself: openssl req -new -key privkeyfile -out csrfile ... followed by openssl x509 -req -in csrfile -signkey privkeyfile -out certfile .... There are many existing Qs, many (most?) going back many years, already covering both of these options.

This will 'work' in the sense that openssl pkcs12 -export can create, and Java(*) can read, a file containing the privatekey and the self-signed cert. However, this keystore will be useless for almost all of the things you would want to use a Java keystore for. For example, you can configure an HTTPS or other SSL/TLS server using this keystore and it will run, but almost all clients when they try to connect will see that the certificate is not from a valid CA and abort. A few things, like postman, will ignore the cert error and proceed, and a few more, like curl --insecure, can be configured to, but things like browsers and applications won't work. Similarly, you might use such a keystore in Java to sign a PDF document, but anything that reads that document will reject it because the cert is not from a valid CA. Etc.

(*) with Java 8u60 up, reading PKCS12 should 'just work'; below/before that special configuration or sometimes coding may be needed, but JCA had the capability.

Thus the way to get a useful PKCS12 keystore is to use openssl req -new to create a CSR, send the CSR to a CA and obtain a 'real' cert (which may cost money, but there are some free CAs, and at least one, LetsEncrypt, is well trusted), and use openssl pkcs12 -export to put that cert, plus any needed intermediate or 'chain' cert(s), and the privatekey, all in a PKCS12. The chain cert(s) needed vary depending on the CA used and type of cert obtained, but every public CA operating this century will need at least one; the CA should either document what chain cert(s) you should use, or provide it(them) to you alongside or 'bundled' with your end-entity 'leaf' cert, or both.

  • I don't remember why I wanted to do the conversion, too long ago :-) But your explanation makes sense. Strange I did not find that during my Googling. Thank you! – tbeernot Jul 22 at 6:33

OpenSSL does not support PPK files. Only PuTTY tools do. You can use PuTTYgen to convert PPK to PEM. And then you should be able to convert PEM to PKCS12.


As @"Martin Prikryl" already mentioned, OpenSSL does not support PPK files and you need to install putty-tools. After that you execute puttygen YOUR_PRIVATE.ppk -O private-openssh -o your_private_id for your private key and puttygen YOUR_PUBLIC.ppk -O public-openssh -o your_public_id for your public key.

  • Although private-openssh is identical to the PEM format that OpenSSL expects, public-openssh is something entirely different and unnecessary in this case. – user1686 Jul 17 '19 at 6:43
  • 1
    That is what I did; both the RSA and OPENSSH format. And that is what I try to convert, otherwise I would get a "no private key found" error, because it cannot read the putty format. – tbeernot Jul 17 '19 at 6:47
  • Maybe the file suffix is of influence... – tbeernot Jul 17 '19 at 6:55
  • 2
    ...then why is the main post talking about converting a PPK file if you're converting a PEM file? – user1686 Jul 18 '19 at 6:15
  • Because that is the overall process I'm trying to achieve; a ppk is the starting point. I hope there is another way to get from that to a java keystore file. – tbeernot Jul 19 '19 at 6:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.