Why do I get the error "Cannot store non-PrivateKeys" when creating an SSL Socket in Java?

ibm-midrange, java, ssl

Solution

Instead of using an ephemeral keystore, you could handle everything within a single `SSLContext`.

You would need to initialise your `SSLContext` using an custom `X509KeyManager` instead of using the one given by the default `KeyManagerFactory`. In this `X509KeyManager`,`chooseServerAlias(String keyType, Principal[] issuers, Socket socket)` should return a different alias depending on the local address obtained from the socket.

This way, you wouldn't have to worry about copying the private key from one keystore to another, and this would even work for keystore types from which you can't extract (and thus copy) but only use the private key, e.g. PKCS#11.

Problem

I am working on an older IBM iSeries (IBM-i, i5OS, AS/400, etc), with a Java 5 JVM (Classic, not ITJ J9) on O/S version V5R3M0. Here is the scenario in a nutshell: - I created a key-store of type JKS using Portecle 1.7 (Note: I did try converting my key-store to JCEKS but that was rejected as an unsupported format, so it appears that JKS is the only option with the iSeries machine (at least the version I am on). - I then created a key-pair and CSR and sent the CSR to Thawte to be signed. - I imported the signed certificate from Thawte successfully using the PKCS#7 format to import the entire certificate chain, which included my certificate, the Thawte intermediary and the Thawte server root. This all worked as expected. However, when I ran up the JVM, configured properly to point to the store and supply it's password (which I have done in the past with self-signed certificates created in Portecle for testing), and try to start my web server on 443, I get the following security exception: ``` java.security.KeyStoreException: Cannot store non-PrivateKeys ``` Can anyone tell me where I went wrong, or what I should check next?

Original source