首页 文章

Chrome中的Java HTTPS服务器“不支持的协议错误”

提问于
浏览
0

我正在使用Java进行自定义HTTP / 1.1服务器实现 . 它在HTTP模式下工作正常,但我也想支持HTTPS . 我还没有为服务器生成证书,但它至少应该尝试连接 . 我将协议和密码套件设置为与google.com(TLS 1.2,ECDHE_RSA,AES_128_GCM)相同的设置,因此我知道Chrome支持它们 .

但是当我尝试连接到Chrome中的 https://localhost 时,它会给出ERR_SSL_VERSION_OR_CIPHER_MISMATCH(localhost使用不支持的协议)错误 . 在Java方面,我得到"no cipher suites in common"错误 .

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 was tampered with, or password was incorrect 错误 .

1 回答

  • 0

    就像我在评论中所说的那样,在 keyStore.load 中使用"password"解决了这个问题 .

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

相关问题