2017-07-17 17 views
0

JavaでカスタムHTTP/1.1サーバー実装を作成しています。 HTTPモードで正常に動作していますが、HTTPSもサポートしたいと考えています。私はまだサーバーの証明書を生成していませんが、少なくとも接続しようとしているはずです。プロトコルと暗号スイートをgoogle.com(TLS 1.2、ECDHE_RSA、AES_128_GCM)と同じ設定にして、Chromeがサポートしていることを知っています。Java HTTPSサーバー「Chromeでサポートされていないプロトコルエラー」

しかし、Chromeでhttps://localhostに接続しようとすると、ERR_SSL_VERSION_OR_CIPHER_MISMATCH(localhostはサポートされていないプロトコルが使用されます)エラーが発生します。 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は、キーストアが改ざんされたスロー、またはパスワードがエラー正しくありませんでした。

+0

コードでパスワードとして「パス」ではなく「パスワード」を指定します。 –

+0

ありがとうございました。 "パスワード"を使用しました。しかし、本当になぜそれはなぜか分かりません。 – Pecacheu

答えて

0

私がコメントで言ったように、で "パスワード"を使用して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; 
} 
関連する問題