|
import com.sun.net.httpserver.HttpsConfigurator; |
|
import com.sun.net.httpserver.HttpsParameters; |
|
import com.sun.net.httpserver.HttpsServer; |
|
|
|
import javax.net.ssl.KeyManagerFactory; |
|
import javax.net.ssl.SSLContext; |
|
import javax.net.ssl.SSLParameters; |
|
import javax.net.ssl.TrustManagerFactory; |
|
import java.io.FileInputStream; |
|
import java.io.OutputStream; |
|
import java.net.InetSocketAddress; |
|
import java.security.KeyStore; |
|
import java.security.Security; |
|
|
|
public class Test { |
|
|
|
private static final String[] CIPHER_SUITES = new String[] { |
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", |
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", |
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", |
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" |
|
// Cipher strength needs to be 256 bits plus for A+ |
|
// https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide#cipher-strength |
|
// ,"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", |
|
// "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", |
|
// "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", |
|
|
|
}; |
|
|
|
public static void main(String[] args) throws Exception { |
|
|
|
int arg = 0; |
|
int port = Integer.parseInt(args[arg++]); |
|
final String keyStore = args[arg++]; |
|
final String keyStoreType = args[arg++]; |
|
// args[2] == keystore password |
|
|
|
// enable unlimited strength JCA |
|
Security.setProperty("crypto.policy", "unlimited"); |
|
|
|
final HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 0); |
|
|
|
final SSLContext tlsContext = getTLSContext(keyStore, keyStoreType, args[arg++].toCharArray()); |
|
|
|
server.setHttpsConfigurator(new HttpsConfigurator(tlsContext) { |
|
public void configure(HttpsParameters params) { |
|
final SSLContext c = getSSLContext(); |
|
final SSLParameters sslparams = c.getDefaultSSLParameters(); |
|
// use cipher suite order provided by the server |
|
sslparams.setUseCipherSuitesOrder(true); // |
|
sslparams.setCipherSuites(Test.CIPHER_SUITES); |
|
params.setSSLParameters(sslparams); |
|
} |
|
}); |
|
|
|
server.createContext("/", (t) -> { |
|
final String response = "This is the response"; |
|
// HSTS headers 6mo+ max-age required |
|
// https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide#changes-in-2009e-21-january-2014 |
|
t.getResponseHeaders().add("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); // 1yr |
|
t.sendResponseHeaders(200, response.length()); |
|
|
|
final OutputStream os = t.getResponseBody(); |
|
os.write(response.getBytes()); |
|
os.close(); |
|
}); |
|
|
|
server.start(); |
|
} |
|
|
|
private static SSLContext getTLSContext(String keyStoreLocation, String keyStoreType, char[] password) throws Exception { |
|
final KeyStore ks = KeyStore.getInstance(keyStoreType); |
|
ks.load(new FileInputStream(keyStoreLocation), password); |
|
|
|
final KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); |
|
kmf.init(ks, password); |
|
|
|
final TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); |
|
tmf.init(ks); |
|
|
|
final SSLContext sslContext = SSLContext.getInstance("TLS"); |
|
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); |
|
return sslContext; |
|
} |
|
|
|
} |