We had an issue recently with our PKCS#12 keystore that had us stumped for days. When trying to access a SOAP web service over HTTPS (mutual authentication) from a stand-alone application we started getting:
Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
I normally use KeyStore Explorer (KSE) tool when working with stores and certificates. In this case KSE was able to both open the keystore and list the private key and certificates stored within (note: as this store was used for testing it was used as a truststore as well as the keystore).
As the keystore appeared to be valid we attempted another test. This time we used OpenSSL to make the request to our web service. Once again this failed due to a failure in establishing the SSL handshake. This being the case, we had to reconsider our earlier assumption about the validity of our keystore.
Using KSE we exported the private key and its corresponding certificate and then tried to import them into a new keystore (we tried both the PKCS12 and JKS formats). KSE failed to import the private key giving us this cryptic error:
… could not check that the private and public key comprise a key pair
At this point we started thinking that perhaps it was the private key and not the keystore that was the problem. We went back to the team who originally supplied us with the keystore to get some answers. While they could not provide a reason why Oracle’s JRE and its command line keytool could not properly read our keystore they have given us a workaround that got us over this hurdle. So, if you experiencing a similar issue and suspecting your PKCS#12 file, give this a try:
- Import your PKCS#12 file into Windows using Certificate Manager tool and mark it as exportable.
- Re-export the keystore into a new p12 file (we are doing this to determine whether the original keystore format is the cause of the issue, which in our case it was).
Create an empty Java keystore (JKS) and add all necessary certificates into it using the following command:
keytool -import trustcacerts -alias [some alias] -file [path to ca certificate file] -keystore [you keystore].jks
Now we can add the private key (the one we exported into the p12 file using Windows) into the new JKS keystore using this command:
keytool -importkeystore -srckeystore [your new PKCS#12 keystore].p12 -srcstoretype PKCS12 -destkeystore [yourkeystore].jks - deststoretype JKS
- Once this is done, your new JKS keystore should now work with your Oracle JRE.
Unfortunately, I can neither take credit for the solution described above nor provide any more insight into why this occurred in the first place. From what I can tell, the Oracle’s JRE (and even the keytool) simply could not properly read the original p12 keystore file even though KSE was kind-of working. I will update this post if I ever discover the root cause.