You cannot split the keystore between the client and server because the keystore contains a private key. During authentication, the client skips certificates with private keys. As stated above, you need to deploy a trust server on the client side.
Certificates in the keystore do not behave the same, depending on how you generated or imported them.
The imported type of certificate entry (with a detailed listing of the entire keystore with -list -v ) is "trustedCertEntry". The generated certificate entry type is "PrivateKeyEntry". When you export a certificate, you only export its public key and an optional link to its issuer.
It looks like you need to export the self-signed certificate to the keystore as a trusted certificate in your trusted store (the names here make sense).
I would not do this because the SSL / TLS implementation probably does not support it. From a real-world point of view, this is like deploying a Verisign secret private key on some obscure web server for signing random pages, while the sole purpose of this private key is to remain secure and sign other certificates. SSL / TLS developers will probably not pollute their code with this use case, and in any case, the KeyUsage certificate extension may limit the use of the certificate for signing, preventing encryption.
This is why I suggest rebuilding the certificate chain for your test.
The keytool documentation contains an interesting part on chaining ( -gencert ), but this is a very skeletal example that does not cover key storage relationships. I improved it to mimic a third-party certificate authority.
The interim store of their-keystore.jks is a certificate issuing authority. I pass him the certificate chain ca2 -> ca1 -> ca with ca , which is considered as the root certificate. A chain is displayed with each certificate without a root (namely ca1 and ca2 ), referring to their issuer as Certificate[2] . Please note that each certificate is a "PrivateKeyEntry".
Then I pass my-keystore.jks these certificates in order: ca , ca1 , ca2 . I import ca using the -trustcacerts , which means that it becomes the root certificate. In my-keystore.jks each imported certificate is now "trustedCertEntry", which means that there is only a public key. Relations with the issuance are displayed only in the "Issuer" field, but this is normal, because trust relations are most important during import.
At this point, my-keystore.jks simulating an environment containing several trusted certificates, such as the new JRE. their-keystore.jks imitates the owners of these certificates, who have the right to sign certificate requests.
So I: I create a self-signed certificate e1 in my-keystore.jks , it is signed by ca2 (via their-keystore.jks ) and imports the result back into my-keystore.jks . e1 is still "PrivateKeyEntry" (since its private key remains in my-keystore.jks ), but now I have created the following chain: e1 -> ca2 -> ca1 . It seems that ca1 -> ca implicit if ca is a certification authority.
To create a trusted store, I simply import the certificates ca , ca1 and ca2 in the same way as for my-keystore.jks . Please note: I do not import e1 , since I expect the SSL / TLS client to check it on ca2 .
I think this is pretty close how everything works in the real world. It's nice that you have full control of the certificates and are not dependent on JRE cacerts.
Here is the code that I speak in practice. It seems to work with Jetty (client and server) until you turn off the certificate revocation list (topic left the next day).
#!/bin/bash rm their-keystore.jks 2> /dev/null rm my-keystore.jks 2> /dev/null rm my-truststore.jks 2> /dev/null echo "====================================================" echo "Creating fake third-party chain ca2 -> ca1 -> ca ..." echo "====================================================" keytool -genkeypair -alias ca -dname cn=ca \ -validity 10000 -keyalg RSA -keysize 2048 \ -ext BasicConstraints:critical=ca:true,pathlen:10000 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -genkeypair -alias ca1 -dname cn=ca1 \ -validity 10000 -keyalg RSA -keysize 2048 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -genkeypair -alias ca2 -dname cn=ca2 \ -validity 10000 -keyalg RSA -keysize 2048 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -certreq -alias ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -gencert -alias ca \ -ext KeyUsage:critical=keyCertSign \ -ext SubjectAlternativeName=dns:ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -alias ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass