使用“创建纯Java HTTPS服务器”;单面“;认证?

使用“创建纯Java HTTPS服务器”;单面“;认证?,java,https,Java,Https,我可以很容易地创建一个我需要的HTTP纯Java服务器。但是,像这样的HTTPS服务器: package httpstest; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import

我可以很容易地创建一个我需要的HTTP纯Java服务器。但是,像这样的HTTPS服务器:

package httpstest;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class HttpsTest {

    public static void main(String[] args) throws Exception {
        HttpsServer server = HttpsServer.create(new InetSocketAddress(8000), 0);
        server.setHttpsConfigurator(new HttpsConfigurator(createSSLContext()));
        server.createContext("/test", new TestHandler());
        server.setExecutor(null); // creates a default executor
        server.start();
    }

    private static SSLContext createSSLContext() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream is = new FileInputStream("server.crt");
        InputStream caInput = new BufferedInputStream(is);
        Certificate ca = cf.generateCertificate(caInput);
        caInput.close();

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        return context;
    }

    static class TestHandler implements HttpHandler {

        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "Successfully connected!";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

将编译并运行服务器端,不会出现错误,但会从浏览器中产生SSL错误。服务器似乎希望浏览器具有相同的证书。我希望任何浏览器在没有安装证书的情况下通过HTTPS连接到它(就像有人连接到它一样)

当您是服务器时,您需要在
密钥管理器中安装您的私人证书。
TrustManager
用于与私有客户端证书相对应的公共证书。显然,如果您不想让浏览器抱怨,您需要一个来自可信CA的私人证书。

当您使用HTTPS连接到Google时,该证书已经在您的浏览器中可用,因为它是一个由可信CA签名的证书


要实现您的目的,您必须使用签名证书(您需要为此支付费用,或者有些人使用免费的签名证书,但我不确定最后一个是否可以)

这是可能的。以下是关键代码:

SSLContext sslContext = SSLContext.getInstance("TLS");
char[] keystorePassword = "password".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("filename.jks"), keystorePassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keystorePassword);
sslContext.init(kmf.getKeyManagers(), null, null);
HttpsConfigurator configurator = new HttpsConfigurator(sslContext);