Java https://localhost (SSL) - 客户端是否可以不安装证书实现连接?

4
阅读以下内容后,我仍然无法制作最基本的 https://localhost 独立安装免费 Web 服务器 Java 应用程序。它需要是无库的,使用 Java 8,并接受来自浏览器的连接,而无需先安装任何特殊客户端证书。我不清楚这是否适用于自签名证书,因为它只需要在“本地主机”上工作。
以下是一些相关链接: 到目前为止,我已经使用以下命令生成了一些密钥文件:
openssl genrsa -aes128 -out privkey.pem 2048  # makes privkey.pem
openssl req -new -x509 -key privkey.pem # makes cert.crt

我已经拼凑出最基本的Kotlin设置函数

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}" }

但是我不知道如何完成它:我需要创建一个lig.keystore文件吗?甚至在没有在客户端浏览器上安装证书的情况下是否可以完成这个操作?


1
您需要将密钥库导入到JVM运行时中。自签名证书只会在浏览器中给您一个警告,您必须自己信任该签名证书。我曾经在企业环境中看到过这个问题成为一个巨大的问题,因为公司有安全策略防止这种情况的发生。 - Derrops
为什么要在本地主机上使用HTTPS?有何意义? - user207421
@ejp 我想从一个SSL保护的Web服务器加载一个HTML文件,该文件(可选地)包含一个本地提供的javascript文件。当我试图从非SSL的http://localhost/thefile.js提供js文件时,浏览器正确地阻止了它。 - Benjamin H
@Snickers3192 糟糕!我就怕会出现这种情况。我本来希望"localhost"能够通过错误检查,但如果不行的话...真是遗憾。 - Benjamin H
就像@EJP所说,本地主机内没有使用SSL的任何意义,但是由于政策或政治原因,我已经看到了它用于测试目的。如果需要,基本上可以通过在前面放置代理来解决这个问题,即浏览器-> HTTP->代理-> HTTPS->服务器。 - Derrops
@Snickers3192 - 除了你需要使用真实的IP代理,提供真实的证书,以及绑定、打开端口等操作来允许代理与“最小化”服务器通信之外,其他都没问题。 - Stephen C
2个回答

5

通过HTTPS在客户端(浏览器)和服务器之间建立安全连接有两种常见方法:

  1. 您可以获取由用户的Web浏览器默认信任的根认证机构(CA)签名的服务器SSL证书。

  2. 您可以生成自签名的SSL证书,并要求用户将其导入其Web浏览器作为受信任的证书。

到目前为止,您所做的似乎是在服务器端生成带有自签名证书的密钥库并(或多或少地)配置Kotlin服务器以使用它。问题在于客户端(浏览器)。没有安全的方法让浏览器信任自签名证书,除非用户或用户的系统管理员参与。(安全...是指对用户而言的安全!)

而且,没有合法的CA应该为“localhost”发行SSL证书;例如:https://www.ssl2buy.com/wiki/how-to-get-ssl-certificate-for-web-applications-that-runs-on-localhost

陷入僵局。

好的,让我们退后一步。使用HTTPS / SSL的目的是确保:

  1. 用户的Web浏览器正在与正确的服务器交流,而不是冒充它的其他服务器。

  2. 浏览器和服务器之间的连接是加密的,以便没有第三方可以窥探流量。

但您正在尝试为 localhost 连接执行此操作。 localhost IP地址是一个环回地址。 除非操作系统内核受到破坏,否则可以保证通过环回连接发送的网络数据包不会离开主机。

  1. 您可以解决“冒充”问题。 假设用户的计算机未被破坏,没有其他人可以在用户的计算机上启动“假”服务器。

  2. 您可以解决“窥探”问题。 假设用户的计算机未被破坏:

    • 数据包不会离开主机,因此无法在任何“外部”网络上进行窥探。
    • 唯一可以在环回网络上“窥探”数据包的人是用户本身。
所以,解决方案很简单。在“localhost”连接中使用“http”。它应该是安全的...假设用户的机器没有被入侵。
注意:如果用户的机器已被入侵,则坏人有其他方法可以拦截SSL无法保护的流量。

首先,感谢您的解释。接下来的问题是,如果我在使用本地主机时创建了一个安全的cookie,那么如果它正在运行HTTP而不是HTTPS,它会被发送到本地主机吗?如果是这样,那么安全的cookie可以配置为发送到非HTTPS连接,这不应该是这种情况;如果不是这样,那么像您在答案中指出的那样,本地主机就不安全了。请解释一下。 - JpersaudCodezit
1
除了不在与本地主机通信的应用程序上设置secure cookie之外,没有好的解决方案。请参阅https://softwareengineering.stackexchange.com/questions/310720/make-browser-allow-secure-cookie-over-http - Stephen C
1
实际上,我的回答并没有说本地主机不安全。我所说/暗示的是,如果有人(即黑客)能够拦截环回设备上的流量,那么这可能是你最不用担心的问题。(而且如果你使用https,他们可能可以在任何接口上拦截流量!) - Stephen C
1
最后,如果您觉得需要在127.0.0.1上使用https,那么您唯一的选择就是使用自签名证书。您可以设置自己的私有CA并为127.0.0.1发行证书,但这可能是危险的。证书+私钥将在任何信任您的私有CA的主机上工作。您组织中可以访问安装了证书+密钥的计算机的人员可能会将其用于恶意目的。 - Stephen C

0

另一个具体情况:

我正在面对一个从https加载本地数据的Web应用程序,该应用程序将在http://localhost上加载。

Safari Web浏览器由于在安全流程(https)中存在不安全通信(http)而被阻止。

这种行为可能会引起讨论,但在这种情况下,针对localhost的自签名证书将有所帮助,即使Safari浏览器发出警告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接