Note that there are some explanatory texts on larger screens.

plurals
  1. POHow should I do hostname validation when using JSSE?
    primarykey
    data
    text
    <p>I'm writing a client in Java (needs to work both on the desktop JRE and on Android) for a proprietary protocol (specific to my company) carried over TLS. I'm trying to figure out the best way to write a TLS client in Java, and in particular, make sure that it does hostname validation properly. (<strong>Edit:</strong> By which, I mean checking that the hostname matches the X.509 certificate, to avoid man-in-the-middle attacks.)</p> <p>JSSE is the obvious API for writing a TLS client, but I noticed from the "<a href="https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html" rel="nofollow noreferrer">Most Dangerous Code in the World</a>" paper (as well as from experimentation) that JSSE doesn't validate the hostname when one is using the SSLSocketFactory API. (Which is what I have to use, since my protocol is not HTTPS.)</p> <p>So, it appears that when using JSSE, I have to do hostname validation myself. And, rather than writing that code from scratch (since I would almost certainly get it wrong), it seems that I should "borrow" some existing code that works. So, the most likely candidate I've found is to use the Apache HttpComponents library (ironic, since I'm not actually doing HTTP) <s>and use the org.apache.http.conn.ssl.SSLSocketFactory class in place of the standard javax.net.ssl.SSLSocketFactory class</s>.</p> <p>My question is: is this a reasonable course of action? Or have I completely misunderstood things, gone off the deep end, and there's actually a much easier way to get hostname validation in JSSE, without pulling in a third-party library like HttpComponents?</p> <p>I also looked at BouncyCastle, too, which has a non-JSSE API for TLS, but it appears to be even more limited, in that it doesn't even do certificate chain validation, much less hostname validation, so it seemed like a non-starter.</p> <p><strong>Edit:</strong> This question <a href="https://stackoverflow.com/a/17979954/372643">has been answered</a> for Java 7, but I'm still curious what the "best practice" is for Java 6 and Android. (In particular, I have to support Android for my application.)</p> <p><strong>Edited again:</strong> To make my proposal of "borrow from Apache HttpComponents" more concrete, I've created a <a href="https://github.com/ppelleti/host-vfy" rel="nofollow noreferrer">small library</a> which contains the HostnameVerifier implementations (most notably StrictHostnameVerifier and BrowserCompatHostnameVerifier) extracted from Apache HttpComponents. (I realized all I need are the verifiers, and I don't need Apache's SSLSocketFactory as I was originally thinking.) If left to my own devices, this is the solution I will use. But firstly, is there any reason I <em>shouldn't</em> do it this way? (Assuming that my goal is to do my hostname validation the same way https does. I realize that itself is open to debate, and has been discussed in the thread on the cryptography list, but for now I'm sticking with HTTPS-like hostname validation, even though I'm not doing HTTPS.)</p> <p>Assuming there's nothing "wrong" with my solution, my question is this: is there a "better" way to do it, while still remaining portable across Java 6, Java 7, and Android? (Where "better" means more idiomatic, already widely in use, and/or needing less external code.)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload