简体   繁体   中英

java https://localhost (SSL) - possible without installing certs on client?

After reading the following, I'm still stuck on making the barest-minimum https ://localhost stand-alone install-free webserver java app. It needs to be library-free, use Java 8, and accept connections from the browser without first installing any special client certs. I'm unclear if this is at all possible with self-signed certs because it only has to work for "localhost".

So far I've generated some key files using

openssl genrsa -aes128 -out privkey.pem 2048  # makes privkey.pem
openssl req -new -x509 -key privkey.pem # makes cert.crt

and I've cobbled together the bare minimum Kotlin setup function

private fun ssl():SSLServerSocketFactory {
    val password = "MYPASSWORD".toCharArray()
    val kmf = KeyManagerFactory.getInstance("SunX509")
    val tmf = TrustManagerFactory.getInstance("SunX509")
    val sslContext = SSLContext.getInstance("TLS")

    // initialise the keystore
    KeyStore.getInstance("JKS").let { ks->
        FileInputStream("lig.keystore").use {
            ks.load(it, password)
        }
        kmf.init(ks, password)
        tmf.init(ks)
    }

    // setup the HTTPS context and parameters
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null)
    return sslContext.serverSocketFactory
}
ssl().createServerSocket().use { serverSocket ->
            serverSocket.reuseAddress = true
            serverSocket.bind(InetSocketAddress(port))
            logger.info { "WebServer ready and listening on ${serverSocket.localPort}" }

But I'm having trouble how to finish it off: Do I need to make a lig.keystore file? Can this even be done without installing certs on the client's browser?

There are two common approaches to getting a secure connection between a client (browser) and server via HTTPS:

  1. You can obtain SSL certificate for the server that is signed by a Root Certification Authority (CA) that is trusted by the user's web browser by default.

  2. You can generate a self-signed SSL certificate, and have the user import it into their web browser as a trusted cert.

What you have done so far seems to be to generate a server-side keystore with a self-signed cert in it and (more or less) configured the Kotlin server to use it. The problem is the client (browser). There is no safe way to get the browser to trust the self-signed cert without the involvement of the user or the user's sysadmin. (Safe ... as in safe for the user!)

And no legitimate CA should ever issue an SSL cert for "localhost"; eg https://www.ssl2buy.com/wiki/how-to-get-ssl-certificate-for-web-applications-that-runs-on-localhost

Impasse.

OK, so lets step back. The purpose of using HTTPS / SSL is to ensure that:

  1. The user's web browser is talking to the correct server, and not some other server that is impersonating it.

  2. The connection between the browser and the server is encrypted so that no third party can snoop on the traffic.

But you are trying to do this for a localhost connection. The localhost IP address is a loopback address. Unless the OS kernel is compromised, you are guaranteed that network packets sent via a loopback connection will not leave the host.

  1. You can dismiss the "impersonation" problem. Assuming that the user's machine has not been compromised, nobody else can launch a "fake" server on the user's machine.

  2. You can dismiss the "snooping" problem. Assuming that the user's machine has not been compromised:

    • The packets won't go off-host, so they can't be snooped on any "external" networks.
    • The only person who can "snoop" the packets on the loopback network is the user him / herself.

So, the solution is simple. Use "http" for your "localhost" connection. It should be secure ... assuming that the user's machine has not been compromised.

Note: if the user's machine has been compromised , then the bad guys have other ways to intercept the traffic that SSL won't protect against.

Another specific case:

I'm facing a web app from https that would load local data at http://localhost

Safari web browser blocks because of unsecure communication (http) in a secure flow (https).

This behavour could be discussed, but in that case self signed certificate for localhost would help., even with a warning from Safari browser.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM