java 我怎么能有一个单一的服务器接受2个不同的网站的安全流量

pftdvrlh  于 2023-01-07  发布在  Java
关注(0)|答案(1)|浏览(95)

使用“让我们加密”,我已经为我的2个网站创建了证书。我使用certbot / openssl / keytool最终得到:站点1.keystore和站点2.keystore
下面是我的简化java代码:

public class TestServer
{
  public static void main(String[] args) throws Exception
  {
    int port = 1443;
    char[] passphrase = "changeit".toCharArray();
    
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(new FileInputStream ("/path/to/site1.keystore"), passphrase);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, passphrase);

    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), null, null);

    SSLServerSocketFactory ssf = null;
    ssf = ctx.getServerSocketFactory();

    ServerSocket ss = ssf.createServerSocket(port);
    while (true)
    {
      Socket socket = ss.accept();
      OutputStream out = socket.getOutputStream();
      String response = "Hello from secure server";
      out.write(("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: " + response.length() + "\r\n\r\n" + response).getBytes());
      out.flush();
      socket.close();
    }
  }
}

如果我使用site1.keystore,我可以连接到site 1如果我使用site2.keystore,我可以连接到site 2到目前为止一切顺利...
为了能够连接到两个站点,我将两个密钥存储库合并到一个all.keystore中
不幸的是,它并不像预期的那样工作...也许有人知道缺少了什么?

guykilcj

guykilcj1#

在挖掘了“服务器名称指示”(谢谢luk 2302)后,我发现了两个可能的解决方案。最简单的一个是为我的两个站点使用一个证书;这可以通过以下方式实现:

sudo certbot certonly --force-renewal --standalone -d site1.com -d site2.com ...

然后像往常一样构建密钥库。
如果我仍然希望每个站点有一个证书,解决方案会更加复杂:接受任何套接字连接,读取并分析TLS报头,获取服务器名称目的地,然后我们知道哪一个是所需的证书。
关于这个问题有一个很好的技术说明:https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SNIExamples

相关问题