Creating a TLS/SSL server with HttpsServer - java

I tried all day do make a server TLS/SSL HTTPS with java. Can someone help me?
This is my code
static class MyHandler implements HttpHandler {
#Override
public void handle(HttpExchange t) throws IOException {
System.out.println("called");
String response = "This is the response";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
static HttpsServer server = null;
static int port = 9000;
public static void main(String[] args) throws Exception {
String keystoreFilename = "/home/kratess/" + "mykey.keystore";
char[] storepass = "mypassword".toCharArray();
char[] keypass = "mypassword".toCharArray();
String alias = "alias";
FileInputStream fIn = new FileInputStream(keystoreFilename);
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(fIn, storepass);
// display certificate
Certificate cert = keystore.getCertificate(alias);
System.out.println(cert);
// setup the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, keypass);
// setup the trust manager factory
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
server = HttpsServer.create(new InetSocketAddress(port), 0);
// create ssl context
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
// setup the HTTPS context and parameters
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
server.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
public void configure(HttpsParameters params) {
try {
// initialise the SSL context
SSLContext c = SSLContext.getDefault();
SSLEngine engine = c.createSSLEngine();
params.setNeedClientAuth(true);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
// get the default parameters
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
params.setSSLParameters(defaultSSLParameters);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Failed to create HTTPS server");
}
}
});
System.out.println("server started at " + port);
server.createContext("/test", new MyHandler());
server.setExecutor(null);
server.start();
}
The server starts but it and the certificate doesn't work on chrome.
The certificate print in the console and is all complete.
Chrome gives that response ERR_EMPTY_RESPONSE
Also, HttpHandler isn't called.
Where am I wrong? If this solution doesn't work can someone suggest me what I have to use? I need to code this HTTPS for creating a WebHook page (required SSL)

Related

SSLSocket.getInputStream() hangs when called Java 11

I am writing a test class for a networking module which establishes a SSL connection used for sending messages. The Junit 4 test class sets up a client side keystore and truststore along with a server side keystore. These variables are used in setting up client side and server side SSLContexts from which I get SSLServerSocket and SSLSocket necessary for setting up a connection through their respective factories.
The SSLServerSocket successfully accepts the connection of my SSLSocket on localhost at the same port. However when I call the SSLSocket.getInputStream() method on the server side socket it hangs whereas calling the SSLSocket.getOutputStream() mehtod on the client side is successful. I am aware that this stage is responsible for initiating the SSL handshake but through my search I have found little on what could be causing a single side to hand. Someone elses post on a separate site mentioned that is could be a reverse dns lookup hanging how would I prevent this? I also tried explicitly starting the handshake in the first of the two Callable threads which hung in a similar fashion. This is my test class:
public class ReceiverClientThreadTest {
// ADD REG AND A SINGLE NETWORK
// ESTABLISH A TLS CONNECTION BETWEEN TWO POINTS WITH
private final static String KEY_MANAGER = "SunX509";
private final static String TLS_VERSION = "TLSv1.2";
private final static String RNG_ALGORITHM = "DEFAULT";
private final static String RNG_PROVIDER = "BC";
private static final String PROVIDER = "BC";
private static final String KEYSTORE_TYPE = "PKCS12";
private static KeyStore keyStore1, keyStore2, trustStore2;
private SSLSocket serverSocket;
private SSLSocket clientSocket;
#BeforeClass
public static void setUp() throws SQLException, GeneralSecurityException, OperatorCreationException, IOException {
String name1 = "localhost", name2 = "client";
KeyPair kp1 = SecurityUtilities.generateKeyPair();
KeyPair kp2 = SecurityUtilities.generateKeyPair();
X509Certificate cert1 = SecurityUtilities.makeV1Certificate(kp1.getPrivate(), kp1.getPublic(), name1);
X509Certificate cert2 = SecurityUtilities.makeV1Certificate(kp2.getPrivate(), kp2.getPublic(), name2);
keyStore1 = KeyStore.getInstance(KEYSTORE_TYPE, PROVIDER);
keyStore2 = KeyStore.getInstance(KEYSTORE_TYPE, PROVIDER);
trustStore2 = KeyStore.getInstance(KEYSTORE_TYPE, PROVIDER);
keyStore1.load(null, null);
keyStore1.setKeyEntry(name1, kp1.getPrivate(), "relaypass".toCharArray(), new X509Certificate[]{cert1});
// keyStore2.load(null, null);
// keyStore2.setKeyEntry(name2, kp2.getPrivate(), null, new X509Certificate[]{cert2});
trustStore2.load(null, null);
trustStore2.setCertificateEntry(name2, cert1);
// secureSocketManager = new SecureSocketManager(keyStore1, password);
}
#Before
public void init() throws IOException, GeneralSecurityException, InterruptedException, ExecutionException {
SSLServerSocket sslServerSocket = getSSLServerSocket();
SSLSocketFactory sslSocketFactory = getSSLSocketFactory();
ExecutorService pool = Executors.newFixedThreadPool(2);
Callable<SSLSocket> c1 = () -> {
return (SSLSocket) sslServerSocket.accept();
};
Callable<SSLSocket> c2 = () -> {
return (SSLSocket) sslSocketFactory.createSocket("localhost", 2048);
};
Future<SSLSocket> server = pool.submit(c1);
Thread.sleep(1000);
Future<SSLSocket> client = pool.submit(c2);
Thread.sleep(1000);
serverSocket = server.get();
clientSocket = client.get();
}
#After
public void tearDown(){
serverSocket = null;
clientSocket = null;
}
#org.junit.Test
public void endSession(){
Thread test = new Thread(new ReceiverClientThread(serverSocket));
test.start();
try (ObjectOutputStream output = new ObjectOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()))) {
System.out.println("here");
}catch (IOException e){
fail();
}
}
private SSLServerSocket getSSLServerSocket() throws GeneralSecurityException, IOException {
char[] entryPassword = "relaypass".toCharArray();
// COULD ADD PROVIDER IN THESE FOR CONSISTENCY
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX", "BCJSSE");
keyManagerFactory.init(keyStore1, entryPassword);
// specify TLS version e.g. TLSv1.3
SSLContext sslContext = SSLContext.getInstance(TLS_VERSION, "BCJSSE");
sslContext.init(keyManagerFactory.getKeyManagers(),null, null);
SSLServerSocketFactory fact = sslContext.getServerSocketFactory();
return (SSLServerSocket) fact.createServerSocket(2048 );
}
private SSLSocketFactory getSSLSocketFactory() throws GeneralSecurityException{
char[] entryPassword = "relaypass".toCharArray();
// COULD ADD PROVIDER IN THESE FOR CONSISTENCY
// KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER, "BCJSSE");
// keyManagerFactory.init(keyStore1, entryPassword);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX", "BCJSSE");
trustManagerFactory.init(trustStore2);
// specify TLS version e.g. TLSv1.3
SSLContext sslContext = SSLContext.getInstance(TLS_VERSION, "BCJSSE");
sslContext.init(null,trustManagerFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
This is the class which it is testing and the only relevant line, the one where the code hangs is commented as such:
public class ReceiverClientThread implements Runnable {
private final SSLSocket sslSocket;
public ReceiverClientThread(SSLSocket sslSocket) {
this.sslSocket = sslSocket;
}
public void run() {
try (ObjectInputStream input = new ObjectInputStream(new BufferedInputStream(sslSocket.getInputStream()))) {
System.out.println("here");
} catch (IOException e) {
}
}
}
Thanks
You could set a timeout on your sslSocket, so that if it hangs during stream read, it will only hang for a set period of time and then will throw an exception. This way the thread will not just hang indefinitely.
sslSocket.setSoTimeout(120000); // timeout of 2 min

How to connect to private url with private ssl certificate

I am trying to connect my android app to a url belonging to a private company in order to retrieve and send information. When I do so however I receive an error Trust anchor for certification path not found, the ssl certificate for the url is valid though, I did research and I used the following code I used to trust the certificate in a class Http TrustManager
public class HttpsTrustManager {
public void trust() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext context = null;
try {
context = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
context.init(null, tmf.getTrustManagers(), null);
} catch (KeyManagementException e) {
e.printStackTrace();
}
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("https://systems.syspearl.com/api");
HttpsURLConnection urlConnection =
(HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
IOUtils.copyStream(in,out);
}
And this is how I call it in the main activity
new HttpsTrusrtManger().trust();
This doesn't work however. Please render necessary help

error:0c0890ba:ASN.1 encoding routines:asn1_check_tlen:WRONG_TAG

I am trying to implement ssl support in my volley request (also I saw answers in SO with similar issues, but it does not help me)
With help of this article I converted my certificate extension from .cer to .bks
That according to this SO answer I do next
mRequestQueue = Volley.newRequestQueue(this, hurlStack);
private HurlStack hurlStack = new HurlStack()
{
#Override
protected HttpURLConnection createConnection(URL url) throws IOException
{
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) super.createConnection(url);
try
{
httpsURLConnection.setSSLSocketFactory(getSSLSocketFactory());
httpsURLConnection.setHostnameVerifier(getHostnameVerifier());
}
catch (Exception e)
{
AppUtils.printLog(Log.ERROR, TAG, e.getMessage());
}
return httpsURLConnection;
}
};
private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.keystore); // this cert file stored in \app\src\main\res\raw folder path
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
// Let's assume your server app is hosting inside a server machine
// which has a server certificate in which "Issued to" is "localhost",for example.
// Then, inside verify method you can verify "localhost".
// If not, you can temporarily return true
private HostnameVerifier getHostnameVerifier()
{
return new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
//return true; // verify always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify("localhost", session);
}
};
}
private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers)
{
final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
return new TrustManager[] {new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers()
{
return originalTrustManager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
certs[0].checkValidity();
}
else
{
originalTrustManager.checkClientTrusted(certs, authType);
}
}
catch (CertificateException e)
{
Log.w("checkClientTrusted", e.toString());
}
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
certs[0].checkValidity();
}
else
{
originalTrustManager.checkServerTrusted(certs, authType);
}
}
catch (CertificateException e)
{
Log.w("checkServerTrusted", e.toString());
}
}
}};
}
And I get next error
com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0c0890ba:ASN.1 encoding routines:asn1_check_tlen:WRONG_TAG
And because of this I get such respond
Bad Request
Bad Request - Invalid Header
HTTP Error 400. The request has an invalid header name.
What am I doing wrong?
Feel free to ask
EDIT 1
so now my getSSLSocketFactory() method look like this
private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException
{
InputStream ksInStream = getResources().openRawResource(R.raw.keystore);
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(ksInStream, SslUtils.KEYSTORE_PASSWORD_SSL.toCharArray());
// Certificate cert = ks.getCertificate("alias");
// ks.setCertificateEntry("ca", cert);
ksInStream.close();
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(ks);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
Now I did not get message about wrong TAG , but I still get bad respond
ResponseJsonString =
Bad Request
Bad Request - Invalid Header
HTTP Error 400. The request has an invalid header name.
In this code you seem to load keystore in BKS format as it would be X.509 encoded certificate, which is bound to fail
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.elalkeystore);
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
You can load keystore like this:
InputStream ksInStream = getResources().openRawResource(R.raw.elalkeystore);
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(ksInStream, keystorePasswordCharArray);
Certificate cert = ks.getCertificate("entryAlias");
ksInStream.close();
Eventually I did not find solution for the issue, I found another approach for implementation
So follow this article
http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/
also if there is any issue about converting .cer to .bks here my SO question and answer
Extension of certificate .cer convert to .bks

javax.net.ssl.SSLHandshakeException: no cipher suites in common no cipher suites in common

Am trying to establish an SSL Connection between a client and a server. But anytime time i try to connect from my client, i get a javax.net.ssl.SSLHandshakeException: no cipher suites in common no cipher suites in common error on my server. I have generated a keystore with signed certificates and i am referencing the keystore on both my client and server. I have gotten fed up after numerous research on this issue and related post on this site hasn't been helpful.
Here is my Server code
public class ServerApplicationSSL {
public static void main(String[] args) {
boolean debug = true;
System.out.println("Waiting For Connection");
int intSSLport = 4444;
{
Security.addProvider(new Provider());
//Security.addProvider(new BouncyCastleProvider());
//System.setProperty("javax.net.ssl.keyStore","C:\\SSLCERT\\NEWAEDCKSSKYE");
//System.setProperty("javax.net.ssl.keyStorePassword", "skyebank");
}
if (debug) {
System.setProperty("javax.net.debug", "all");
}
FileWriter file = null;
try {
file = new FileWriter("C:\\SSLCERT\\Javalog.txt");
} catch (Exception ee) {
//message = ee.getMessage();
}
try {
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("C:\\SSLCERT\\NEWAEDCKSSKYE"), "skyebank".toCharArray());
file.write("Incoming Connection\r\n");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
kmf.init(keystore, "skyebank".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), trustManagers, null);
SSLServerSocketFactory sslServerSocketfactory = (SSLServerSocketFactory) context.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(intSSLport);
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
SSLServerSocket server_socket = (SSLServerSocket) sslServerSocket;
server_socket.setNeedClientAuth(true);
sslSocket.startHandshake();
System.out.println("Connection Accepted");
file.write("Connection Accepted\r\n");
while (true) {
PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);
//BufferedReader in = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
String inputLine;
//while ((inputLine = in.readLine()) != null) {
out.println("Hello Client....Welcome");
System.out.println("Hello Client....Welcome");
//}
out.close();
//in.close();
sslSocket.close();
sslServerSocket.close();
file.flush();
file.close();
}
} catch (Exception exp) {
try {
System.out.println(exp.getMessage() + "\r\n");
System.out.println(exp.getStackTrace() + "\r\n");
file.write(exp.getMessage() + "\r\n");
file.flush();
file.close();
} catch (Exception eee) {
//message = eee.getMessage();
}
}
}
}
Here is my clients code
public String MakeSSlCall(String meternum) {
String message = "";
FileWriter file = null;
try {
file = new FileWriter("C:\\SSLCERT\\ClientJavalog.txt");
} catch (Exception ee) {
message = ee.getMessage();
}
try {
file.write("KeyStore Generated\r\n");
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("C:\\SSLCERT\\NEWAEDCKSSKYE"), "skyebank".toCharArray());
file.write("KeyStore Generated\r\n");
Enumeration enumeration = keystore.aliases();
while (enumeration.hasMoreElements()) {
String alias = (String) enumeration.nextElement();
file.write("alias name: " + alias + "\r\n");
keystore.getCertificate(alias);
file.write(keystore.getCertificate(alias).toString() + "\r\n");
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
kmf.init(keystore, "skyebank".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
file.write("KeyStore Stored\r\n");
SSLContext context = SSLContext.getInstance("SSL");
TrustManager[] trustManagers = tmf.getTrustManagers();
KeyManager[] AllKeysMan = kmf.getKeyManagers();
file.write("Key Manager Length is " + AllKeysMan.length + "\r\n");
for (int i = 0; i < AllKeysMan.length; i++) {
file.write("Key Manager At This Point is " + AllKeysMan[i] + "\r\n");
}
context.init(kmf.getKeyManagers(), trustManagers, null);
SSLSocketFactory f = context.getSocketFactory();
file.write("About to Connect to Ontech\r\n");
SSLSocket c = (SSLSocket) f.createSocket("192.168.1.16", 4444);
file.write("Connection Established to 196.14.30.33 Port: 8462\r\n");
file.write("About to Start Handshake\r\n");
c.startHandshake();
file.write("Handshake Established\r\n");
file.flush();
file.close();
return "Connection Established";
} catch (Exception e) {
try {
file.write("An Error Occured\r\n");
file.write(e.getMessage() + "\r\n");
file.flush();
file.close();
} catch (Exception eee) {
message = eee.getMessage();
}
return "Connection Failed";
}
}
}
can someone please tell me what am doing wrong?
You will have to use SSLContext for this purpose. Check out the sample code which I implemented in one of my applications below. Client context means you become the client and call some back end. Server context means you accept the client requests.
public class SSLUtil {
private static String KEY_STORE_TYPE = "JKS";
private static String TRUST_STORE_TYPE = "JKS";
private static String KEY_MANAGER_TYPE = "SunX509";
private static String TRUST_MANAGER_TYPE = "SunX509";
private static String PROTOCOL = "TLS";
private static SSLContext serverSSLCtx = null;
private static SSLContext clientSSLCtx = null;
public static SSLContext createServerSSLContext(final String keyStoreLocation,
final String keyStorePwd)
throws KeyStoreException,
NoSuchAlgorithmException,
CertificateException,
FileNotFoundException,
IOException,
UnrecoverableKeyException,
KeyManagementException {
if (serverSSLCtx == null) {
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
keyStore.load(new FileInputStream(keyStoreLocation), keyStorePwd.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE);
keyManagerFactory.init(keyStore, keyStorePwd.toCharArray());
serverSSLCtx = SSLContext.getInstance(PROTOCOL);
serverSSLCtx.init(keyManagerFactory.getKeyManagers(), null, null);
}
return serverSSLCtx;
}
public static SSLContext createClientSSLContext(final String trustStoreLocation,
final String trustStorePwd)
throws KeyStoreException,
NoSuchAlgorithmException,
CertificateException,
FileNotFoundException,
IOException,
KeyManagementException {
if (clientSSLCtx == null) {
KeyStore trustStore = KeyStore.getInstance(TRUST_STORE_TYPE);
trustStore.load(new FileInputStream(trustStoreLocation), trustStorePwd.toCharArray());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE);
trustManagerFactory.init(trustStore);
clientSSLCtx = SSLContext.getInstance(PROTOCOL);
clientSSLCtx.init(null, trustManagerFactory.getTrustManagers(), null);
}
return clientSSLCtx;
}
}
Finally make sure you import the trusted server certificate to the client key store. Literally server and client should have different key stores. The key store used in the client side is referred to as client trust store since we are trusting the server certificate here. This article may help.

Create app with SSLSocket Java

I want to create an app use SSLSocket: client send a String to server and server will uppercase that String and send back to client for display.
SSLServer
public class SSLServer {
public static void main(String args[]) throws Exception
{
try{
//Creaet a SSLServersocket
SSLServerSocketFactory factory=(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket=(SSLServerSocket) factory.createServerSocket(1234);
//Tạo 1 đối tượng Socket từ serversocket để lắng nghe và chấp nhận kết nối từ client
SSLSocket sslsocket=(SSLSocket) sslserversocket.accept();
//Tao cac luong de nhan va gui du lieu cua client
DataInputStream is=new DataInputStream(sslsocket.getInputStream());
PrintStream os=new PrintStream(sslsocket.getOutputStream());
while(true) //khi dang ket noi voi client
{
//Doc du lieu den
String input=is.readUTF();
String ketqua=input.toUpperCase();
//Du lieu tra ve
os.println(ketqua);
}
}
catch(IOException e)
{
System.out.print(e);
}
}
}
SSLClient
public class SSLClient {
public static void main(String args[])
{
try
{
//Mo 1 client socket den server voi so cong va dia chi xac dinh
SSLSocketFactory factory=(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket=(SSLSocket) factory.createSocket("127.0.0.1",1234);
//Tao luong nhan va gui du lieu len server
DataOutputStream os=new DataOutputStream(sslsocket.getOutputStream());
DataInputStream is=new DataInputStream(sslsocket.getInputStream());
//Gui du lieu len server
String str="helloworld";
os.writeBytes(str);
//Nhan du lieu da qua xu li tu server ve
String responseStr;
if((responseStr=is.readUTF())!=null)
{
System.out.println(responseStr);
}
os.close();
is.close();
sslsocket.close();
}
catch(UnknownHostException e)
{
System.out.println(e.getMessage());
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
}
When run SSLServer. It displays this error:
javax.net.ssl.SSLException: No available certificate or key corresponds
to the SSL cipher suites which are enabled
I have search and do some ways but.. Can you help me.
This will generate certificate:
keytool -genkey -keystore yourKEYSTORE -keyalg RSA
Enter yourPASSWORD and than start your server with ssl debug information(put yourKEYSTORE into directory with SSLServer.class):
java -Djavax.net.ssl.keyStore=yourKEYSTORE -Djavax.net.ssl.keyStorePassword=yourPASSWORD -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl SSLServer
Than start your client(put yourKEYSTORE into directory with SSLClient.class):
java -Djavax.net.ssl.trustStore=yourKEYSTORE -Djavax.net.ssl.trustStorePassword=yourPASSWORD SSLClient
#corVaroxid's answer is right. But if you want to set configurations programmatically to avoid global settings (like me), you can go like below (Kotlin):
val password = "yourPassword".toCharArray()
val keyStore = KeyStore.getInstance(File("yourKeystorePath.jks"), password)
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(keyStore)
val keyManagerFactory = KeyManagerFactory.getInstance("NewSunX509")
keyManagerFactory.init(keyStore, password)
val context = SSLContext.getInstance("TLS") //"SSL" "TLS"
context.init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, null)
val factory = context.serverSocketFactory
(factory.createServerSocket(LISTENING_PORT) as SSLServerSocket).use { serverSocket ->
logger.trace("Listening on port: $LISTENING_PORT")
// ...
}
Or in Java:
final char[] password = "yourPassword".toCharArray();
final KeyStore keyStore = KeyStore.getInstance(new File("yourKeystorePath.jks"), password);
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("NewSunX509");
keyManagerFactory.init(keyStore, password);
final SSLContext context = SSLContext.getInstance("TLS");//"SSL" "TLS"
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
final SSLServerSocketFactory factory = context.getServerSocketFactory();
try (SSLServerSocket serverSocket = ((SSLServerSocket) factory.createServerSocket(LISTENING_PORT))) {
logger.trace("Listening on port: " + LISTENING_PORT);
// ...
}
Check the certificates that you have installed. Make sure they are supporting the cipher suites that you are negotiating.

Categories

Resources