700 Software
700 Software

Reputation: 87773

Java SSL/TLS client to connect to & verify server using self-signed certificate which is loaded at run-time?

Searching the internet has proved overly-complicated for this particular question. Perhaps you can point me in the right direction?

I have set up an SSL/TLS server (not HTTPS) with a self-signed certificate. I have successfully connected to it and tested using Node.JS

var sock = tls.connect({
  host:'127.0.0.1',
  port:443,
  servername:'foobar',
  ca: fs.readFileSync('foobar-cert.pem')
}, function () {
  if(sock.authorized)
    console.log('secure connection - yea!')
  else
    console.log('Not Secure because ' + sock.authorizationError)
})

But I can't seem to find equivalent sample code in Java.

How can I connect to a TLS server in Java, using a self-signed certificate file for server authentication? The self-signed certificate would be loaded at run-time, and not installed into the computer's shared CA file.

The best answer I have found so far requires an external library. This is my last resort, because I am sure that Java would have what I need built in and I wouldn't need an external library at all.

Edit: Thanks for your quick response on re-opening the question.

Edit: I see my question was closed as duplicate of telling java to accept self-signed ssl certificate. This is not correct as my question has extra requirements, which I stated above:

  • Suggestion: "the certificate...import it in your JVM truststore"
    My requirement "self-signed certificate ... not installed into the computer's shared CA file"

  • Suggestion: "Disable Certificate Validation" (not recommended)
    My requirement "self-signed certificate would be loaded at run-time" (and used for server validation)

  • Suggestion: "import that into your truststore using the keytool"
    My requirement "self-signed certificate ... not installed into the computer's shared CA file"

Upvotes: 4

Views: 10611

Answers (2)

GreyBeardedGeek
GreyBeardedGeek

Reputation: 30088

I wrote a blog post a little while back showing how to do this (including reading the cert at runtime) on Android, but the same code should work on the desktop.

The basic idea is to create a trust store at runtime, read the cert, and add it to the trust store. Then use the custom trust store to create an SSLContext that can be used with SSLSocketFactory.

The example in the blog post passes the SSLSocketFactory to a URLConnection, but you could use SSLSocketFactory's createSocket method to get a socket and work with it directly.

Upvotes: 4

irreputable
irreputable

Reputation: 45433

You may find the answer somewhere in this gigantic document:

http://download.java.net/jdk8/docs/technotes/guides/security/jsse/JSSERefGuide.html

Basically, use SSLSocket for starters. But I don't think you can add certificate at runtime.

Upvotes: 1

Related Questions