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は、キーストアが改ざんされたスロー、またはパスワードがエラー正しくありませんでした。
コードでパスワードとして「パス」ではなく「パスワード」を指定します。 –
ありがとうございました。 "パスワード"を使用しました。しかし、本当になぜそれはなぜか分かりません。 – Pecacheu