简体   繁体   中英

How do I use LetsEncrypt certificates in Java Sun HttpsServer?

Using various results from a lot of googling I've managed to make a Java class that handles downloading of certificates from LetsEncrypt, pretty neat. (Available here if anyone is interested)

With that I get this content in a folder as output:

chain.crt
domain.crt
domain.csr
domain.key
user.key

I've been using a com.sun.net.httpserver.HttpsServer with a self-signed certificate that I followed some guide to generate that gave me a .jks file, which has worked great up until now using test-clients. But now I need browsers to accept the certificate without giving verification errors, so I would like to use the certificates downloaded from LetsEncrypt in this HttpsServer but I have no idea how to go about doing that. I have googled a bit on it but I haven't found anything that has worked for me, though I have to admit I don't really understand most of the things I'm doing here, and I don't even know which of the 5 files above I should try to use.

My current code setting up my HttpsServer with an existing generated .jks file: (Also available here )

  public void initHttpsServer(int port, String certificateFilePath, String sslPassword)
  {
    try
    {
      this.server = HttpsServer.create(new InetSocketAddress(port), 0);
      SSLContext sslContext = SSLContext.getInstance("TLS");
      char[] password = sslPassword.toCharArray();
      KeyStore ks = KeyStore.getInstance("JKS");
      FileInputStream fis = new FileInputStream(certificateFilePath);
      ks.load(fis, password);
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
      kmf.init(ks, password);
      TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
      tmf.init(ks);
      sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
      this.server.setHttpsConfigurator(new HttpsConfigurator(sslContext)
      {
        @Override
        public void configure(HttpsParameters params)
        {
          try
          {
            SSLContext c = SSLContext.getDefault();
            SSLEngine engine = c.createSSLEngine();
            params.setNeedClientAuth(false);
            params.setCipherSuites(engine.getEnabledCipherSuites());
            params.setProtocols(engine.getEnabledProtocols());
            SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
            params.setSSLParameters(defaultSSLParameters);
          }

While looking for solutions I've come across some answers that includes running commands from a cmd to generate different sort of files. I need all of this to work during runtime so ways to do it programmatically is preferred.

Also I have a sort of related question, can I update a running instance of HttpsServer to use newly downloaded certificates when the old LetsEncrypt certificates expire and I have downloaded new ones, or will I have to restart the server?

Any help in figuring out how to make this work is much appreciated.

Aside: calling this JKS file 'certificateFile' is misleading; a JKS (or other keystore like PKCS12) contains usually several certificates, but usually including this case also and critically the privatekey.

Usually the harder part is reading the key file, and since you are using acme4j it handles that for you. Not tested due to lack of infrastructure, but do something like:

KeyPair kp = KeyPairUtils.readKeyPair (new FileReader ("domain.key"));
// add error handling and close much like your getOrCreateKeyPair 
CertificateFactory cf = CertificateFactory.getInstance ("X.509");
Certificate cert0 = cf.generateCertificate (new FileInputStream ("domain.crt"));
Certificate cert1 = cf.generateCertificate (new FileInputStream ("chain.crt"));
// add similar error handling and close

KeyStore ks = KeyStore.getInstance ("jks"); // type doesn't really matter since it's in memory only
ks.load (null); 
ks.setKeyEntry ("anyalias", kp.getPrivate(), password, new Certificate[]{cert0,cert1});

// now create a KMF and KeyManager from this KeyStore,
// optionally a TMF and TrustManager, then SSLContext etc as in your existing code

I don't know if the Sun HttpsServer can change the KeyManager data while running; if I have time later I'll try to look at that. But clearly you need to get it started before changing it is an issue :-)

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