Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HTTPS服务器“;不支持的协议错误“;含铬_Java_Ssl_Https_Server_Tls1.2 - Fatal编程技术网

Java HTTPS服务器“;不支持的协议错误“;含铬

Java HTTPS服务器“;不支持的协议错误“;含铬,java,ssl,https,server,tls1.2,Java,Ssl,Https,Server,Tls1.2,我正在用Java制作一个自定义HTTP/1.1服务器实现。它在HTTP模式下运行良好,但我也希望支持HTTPS。我还没有为服务器生成证书,但它至少应该正在尝试连接。我将协议和密码套件设置为与google.com相同的设置(TLS1.2、ECDHE_RSA、AES_128_GCM),因此我知道Chrome支持它们 但是当我尝试连接到https://localhost在Chrome中,它会给出ERR\u SSL\u VERSION\u或\u CIPHER\u不匹配(本地主机使用不受支持的协议)错误。

我正在用Java制作一个自定义HTTP/1.1服务器实现。它在HTTP模式下运行良好,但我也希望支持HTTPS。我还没有为服务器生成证书,但它至少应该正在尝试连接。我将协议和密码套件设置为与google.com相同的设置(TLS1.2、ECDHE_RSA、AES_128_GCM),因此我知道Chrome支持它们

但是当我尝试连接到
https://localhost
在Chrome中,它会给出ERR\u SSL\u VERSION\u或\u CIPHER\u不匹配(本地主机使用不受支持的协议)错误。在Java方面,我得到了“没有常见的密码套件”错误

Java代码:

public class Server {
    private final String dir;
    private final ServerSocket server;
    private final SSLServerSocket sslServer;

    public static String jarDir() {
        String uri = ClassLoader.getSystemClassLoader().getResource(".").getPath();
        try { return new File(URLDecoder.decode(uri,"UTF-8")).getPath()+File.separator; }
        catch (Exception e) { return null; }
    }

    private static SSLContext createSSLContext(String cert, char[] pass) throws Exception {
        /*//Load KeyStore in JKS format:
        KeyStore keyStore = KeyStore.getInstance("jks");
        keyStore.load(new FileInputStream(cert), pass);

        //Create key manager:
        KeyManagerFactory kmFactory = KeyManagerFactory.getInstance("SunX509");
        kmFactory.init(keyStore, pass); KeyManager[] km = kmFactory.getKeyManagers();

        //Create trust manager:
        TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509");
        tmFactory.init(keyStore); TrustManager[] tm = tmFactory.getTrustManagers();

        //Create SSLContext with protocol:
        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        ctx.init(km, tm, null); return ctx;*/

        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        ctx.init(null, null, null); return ctx;
    }

    Server(String localPath, int port) throws Exception {
        this(localPath, port, 0);
    }

    //Server is being initialized with:
    //new Server("root", 80, 443);

    Server(String localPath, int port, int httpsPort) throws Exception {
        dir = localPath; File fdir = new File(jarDir(), dir);
        if(!fdir.isDirectory()) throw new Exception("No such directory '"+fdir.getAbsolutePath()+"'!");

        //Init Server:
        server = new ServerSocket(port);
        if(httpsPort > 0) {
            SSLContext ctx = createSSLContext("cert.jks", "pass".toCharArray());
            sslServer = (SSLServerSocket)ctx.getServerSocketFactory().createServerSocket(httpsPort);

            //TLS_DH_anon_WITH_AES_128_GCM_SHA256
            sslServer.setEnabledCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"});
            sslServer.setEnabledProtocols(new String[]{"TLSv1.2"});

            //Also does not work, same error:
            //sslServer.setEnabledCipherSuites(sslServer.getSupportedCipherSuites());
            //sslServer.setEnabledProtocols(sslServer.getSupportedProtocols());
        } else sslServer = null;

        /*new Thread(() -> { while(true) try {
            new HTTPSocket(server.accept(), this);
        } catch(Exception e) { Main.err("HTTP Server Error",e); }}).start();*/

        if(httpsPort > 0) new Thread(() -> { while(true) try {
            new HTTPSocket(sslServer.accept(), this);
        } catch(Exception e) { Main.err("HTTPS Server Error",e); }}).start();
    }

    /* ... Other Stuff ... */

}

编辑:我使用
keytool-genkey-keyalg RSA-alias selfsigned-keystore cert.jks-storepass password-validity 360-keysize 2048生成了一个证书,但是现在Java抛出密钥库被篡改,或者密码不正确错误。

就像我在评论中说的,使用“密码”在keyStore.load中解决了该问题

private static SSLContext createSSLContext(String cert, char[] pass) throws Exception {
    //Load KeyStore in JKS format:
    KeyStore keyStore = KeyStore.getInstance("jks");
    keyStore.load(new FileInputStream(cert), "password".toCharArray());

    //Create key manager:
    KeyManagerFactory kmFactory = KeyManagerFactory.getInstance("SunX509");
    kmFactory.init(keyStore, pass); KeyManager[] km = kmFactory.getKeyManagers();

    //Create trust manager:
    TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509");
    tmFactory.init(keyStore); TrustManager[] tm = tmFactory.getTrustManagers();

    //Create SSLContext with protocol:
    SSLContext ctx = SSLContext.getInstance("TLSv1.2");
    ctx.init(km, tm, null); return ctx;
}
在代码中提供“password”而不是“pass”作为密码。谢谢,使用“password”有效。但我不知道为什么。