10

I use SSL to communicate between two components written in Java. I can't use a CA, so I have to self-sign everything. Unfortunately, this means that when I try to handshake, I get a SunCertPathBuilderException. I can create my own X509TrustManager that just trusts everything, but that sort of defeats the purpose of having a signed cert.

I would like, when first making the connection, to prompt the user with "SSL handshake with invalid cert. Add cert to store?" or something so they could have it added for them to their certificate store, like web browsers do at sites with invalid certs. I can find plenty of examples online of adding a cert to the store through the commandline, but I can't figure out how to do it programmatically. Is there a way to do this?

directedition
  • 11,145
  • 18
  • 58
  • 79
  • In my case, the missing piece ended up being to use https://stackoverflow.com/a/5488964/513038 to generate an X509Certificate from the KeyPair I had, then use `truststore.setEntry("dummy", new KeyStore.TrustedCertificateEntry(cert), null);` rather than `setKeyEntry`. (I'd been getting errors like "KeyStoreException: Key protection algorithm not found ... Unsupported key type".) If you already have a cert, like for a remote partner negotiating a connection, you should be able to use that cert in `TrustedCertificateEntry(cert)` instead of generating your own. – Erhannis Jan 04 '22 at 06:50
  • I cobbled together code from many sources to do what you're doing, and then some - programmatically generate certs on both sides, open a TLS connection, ask the user on both sides to trust the other, and if so, add the other's cert to a truststore for use in the future. https://github.com/Erhannis/TlsChannelTest – Erhannis Jan 05 '22 at 02:13

3 Answers3

5

Yes it is possible.

There is some code here that I've used before. I had to modify it to do what I wanted and I suspect that you will too but this should get you close - you aren't trying to import a key so theoretically you should be able to simplify things. In any case you can get an idea of what you'll need.

The JDK JavaDoc for java.security.KeyStore is pretty useful too.

macbutch
  • 3,241
  • 2
  • 27
  • 27
0

Why don't you create your own CA and sign your certificates with that? Then all you would need to do is install the CA own certificate on the machines and every certificate signed by that CA would validate.

Hiro2k
  • 5,254
  • 4
  • 23
  • 28
  • 1
    Because every user will run their own server and needs their own certificate for authentication (so one is distinguishable from another). I suppose I could create a CA, but that would greatly complication the installation procedure, requiring the user to make cert production requests to me. – directedition May 04 '10 at 17:26
0

Why would you need to do this, you are not validating that the client is who they say they are you are only using the certs to encrypt the comms, so a custom trust manager that allows all certs is all you need. What you are asking is possible and from memory also involves a custom trust manager to validate the certificates and store them in the keystore. I can't remember the details, but at least you know it is possible to do it.

t0ne
  • 159
  • 7