18

I have a Java SSL server to which I want my Java SSL client and C++ SSL client to be able to connect. The Java client connects without issues. Now I want to have my C++ SSL client to be able to connect. So for this purpose ,I imagined, that I want to export the serverpub.jks to an .pem file so that my C++ client can load it into its ssl context. But this is not working.

Below is a description of how I created the jks keystores for Java client and server and then how I am trying to export the serverpub.jks to .pem file.

step 1: Generate the Client and Server Keystores

c:\keytool -genkeypair -alias myserverkeys -keyalg RSA -dname "CN=my Server,OU=kl2217,O=kl2217org,L=NYC,ST=NY,C=US" -keypass password -keystore server.jks -storepass password
c:\keytool -genkeypair -alias myclientkeys -keyalg RSA -dname "CN=my Client,OU=kl2217,O=kl2217org,L=NYC,ST=NY,C=US" -keypass password -keystore myclient.jks -storepass password

step 2: Export the server public certificate and create a seperate keystore

c:\keytool -exportcert -alias myserverkeys -file serverpub.cer -keystore myserver.jks -storepass spacex
c:\keytool -importcert -keystore serverpub.jks -alias serverpub -file serverpub.cer -storepass password

step 3: Export the client public certificate and create a seperate keystore

c:\keytool -exportcert -alias myclientkeys -file clientpub.cer -keystore myclient.jks -storepass spacey
c:\keytool -importcert -keystore clientpub.jks -alias clientpub -file clientpub.cer -storepass password

So far so good.

Now here is where I run into problems.

step 4: Convert serverpub.jks to .pem format

c:\keytool -importkeystore -srckeystore serverpub.jks -destkeystore serverpub.p12 -srcstoretype jks -deststoretype pkcs12

And the reply

Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Problem importing entry for alias serverpub: java.security.KeyStoreException: TrustedCertEntry not supported.
Entry for alias serverpub not imported.
Do you want to quit the import process? [no]:

What does this mean? What am I doing wrong?

step 5: Would have been

c:\openssl pkcs12 -in serverpub.p12 -out serverpub.pem

But as you can see I couldn't get that far.

I would really appreciate some help understanding how to do this right.

Thanks

driftwood
  • 2,051
  • 4
  • 21
  • 28
  • 1
    I think you need to get the concepts straight first. `serverpub.jks` contains only a certificate; it has no private keys in it. The PKCS12 format you are trying to export it into expects a key pair, in other words a private key and a public key. – President James K. Polk Jun 21 '14 at 16:53
  • Ah I see. So is there a way to export just the cert to .pem? As I understand it that's all I need to load into C++ client trust store, no? – driftwood Jun 21 '14 at 16:58
  • I'm not sure what you're trying to do. Are you trying to do client-authentication? If so then the client needs its own private key. – President James K. Polk Jun 21 '14 at 17:00
  • So just like the Java client and server mutually authenticate, I want the same thing between C++ client and Java server. – driftwood Jun 21 '14 at 17:04
  • 1
    so `-genkeypair` the client key in its own keystore and export this keystore to a PKCS12 file. Then the client also needs to trust to the server's public key, so that needs to be in the client's trust store. The server needs to trust the client's public key, so that needs to be in the server's trust store. – President James K. Polk Jun 21 '14 at 17:23
  • i already figured it out. its working now. your initial reply helped crack it for me. Thanks. – driftwood Jun 21 '14 at 17:29
  • (1) I guess, it's TLS that you're trying to implement, not SSL, which is not used anymore (2) Do you implement it with mutual client/server authentication? If not, you don't need "myclientkeys" at all and the only thing that you do need is to add your public server's cert to the list of trusted certs on your client. Since C++ doesn't understand JKS you do need to export your server's root cert to PEM first and then use it in the client or add to a list of trusted CA's. The location of the latter list depends on your system. – Oleg Gryb Aug 31 '17 at 23:48

2 Answers2

25

Unfortunately keytool explicitly will not let you export from a trust store since they are of the opinion that PEM files do not support the concept of trusted certificate. So I would use the keystore of cer files instead.

  • From a cer:

    openssl x509 -inform der -in serverpub.cer -out serverpub.pem
    
  • From a keystore:

    keytool -importkeystore -srckeystore server.jks -destkeystore server.p12 -deststoretype PKCS12
    openssl pkcs12 -in server.p12 -nokeys -out server.cer.pem
    openssl pkcs12 -in server.p12 -nodes -nocerts -out server.key.pem
    

or just try

keytool -exportcert -alias myserverkeys -keystore serverpub.jks -rfc -file serverpub.pem
Marc
  • 13,011
  • 11
  • 78
  • 98
Chris Molanus
  • 387
  • 3
  • 7
  • 2
    Where did this come from "PEM files do not support the concept of trusted certificate"? I'm "-1"-ing until this phrase will be either explained or removed. – Oleg Gryb Aug 31 '17 at 23:31
  • 2
    keytool -exportcert worked perfectly for me. Your solution saved my day. Thanks. – user3731930 Jun 18 '19 at 14:08
5

The following simple single line command will export the certificate to PEM format. Yes, you need openssl, keytool alone can't do this.

keytool -exportcert -alias <CERT-ALIAS> -keystore <KEYSTORE-FILE> | openssl x509 -inform DER >cert.pem
Oleg Gryb
  • 5,122
  • 1
  • 28
  • 40
  • 2
    Please explain -1. Doesn't it work? Works fine for me on Linux and Mac. Didn't try on Windows, but should be the same. – Oleg Gryb Aug 31 '17 at 23:29
  • Works fine for me on Windows 10. Openssl isn't strictly required if you use the `-rfc` option to `keytool -exportcert`, which exports using PEM format. – Charlie Reitzel Jan 22 '21 at 18:57