Java to Android Code - java

I have coded this client ssl code for java which works great and sends the wave file to a server. I am trying now to change or use this code on Android but I am having problems doing so. The questions that I have are things such as:
How do I set the pathStore and trustStoreFile(which directories are these on the android)?
Where do I upload the certificate file to(trustStoreFile) ?
Are there any settings that I need to configure?
Is this code what I need to use to accomplish the task of sending the wav file to the server that is listening?
Thanks so much !
Please Help !
Here is the ssl client code in :
package admir.network.ssl.client;
import android.provider.Settings;
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.io.IOUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
//import com.sun.net.ssl.SSLContext;
//import com.sun.net.ssl.TrustManagerFactory;
//import com.sun.net.ssl.TrustManager;
public class test2 {
private static final String HOST = "X.X.X.X";
private static final int PORT = 5000;
String pwd = System.getProperty("user.dir");
final static String pathToStores = System.setProperty("user.dir","user.dir"+"/java/admir.network.ssl.client/");
final static String trustStoreFile = "cert.jks" ; // filename
public String app = System.setProperty("user.dir",pwd);
public static void main(String[] args) throws Exception {
String trustFileName = pathToStores + "/" + trustStoreFile;
char[] passphrase = "xxxxx".toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream(trustFileName), passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
SSLContext context = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
context.init(null, trustManagers, null);
SSLSocketFactory sf = context.getSocketFactory();
Socket s = sf.createSocket(HOST, PORT);
String FILE_TO_SEND = ""+ System.getProperty("user.dir")+"/"+"src"+"/"+"Voice 005.wav"+"";
File soundFile = AudioUtil.getSoundFile(FILE_TO_SEND);
if (s.isBound()){
OutputStream out = s.getOutputStream();
InputStream in = new FileInputStream(soundFile);
IOUtils.copy(in, out);
System.out.println("Done Sending.");
out.close();
}
s.close();
}
}

Related

Unsupported or unrecognized SSL message, cannot be read

I am trying to display the date on an HTTPS website via an SSL server.
I am getting an error thrown on line 31 (I have marked where it is).
I reckon it might be to do with the browser and how it is set up. Since the error is coming from an unsupported message.
Code:
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
public class SSLServer {
final static String pathToStores = "keys";
final static String keyStoreFile = "server-key.pem";
final static String password = "";
final static int port = 8080;
static boolean debug = false;
void doServerSide() throws Exception {
SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
InputStream inputStream = sslSocket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
///////////////////// exception thrown on the line below /////////////////////
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
OutputStream outputStream = sslSocket.getOutputStream();
String httpResponce = "HTTP/1.1 200 OK\r\n\r\n" + new Date();
outputStream.write(httpResponce.getBytes(StandardCharsets.UTF_8));
sslSocket.close();
}
public static void main(String[] args) throws Exception {
String trustFilename = pathToStores + "/" + keyStoreFile;
System.setProperty("java.net.ssl.keyStore", trustFilename);
System.setProperty("javax.net.ssl.keyStorePassword", password);
if (debug) System.getProperty("java.net.debug", "all");
new SSLServer().doServerSide();
}
}
Exception:
Exception in thread "main" javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451)
at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1497)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1403)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:903)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:994)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:178)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:329)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:396)
at SSLServer.doServerSide(SSLServer.java:31)
at SSLServer.main(SSLServer.java:51)
I am using firefox and chrome for testing.
Thanks :)

getLocalCertificates() return null

I'm trying to write a simple ssl server socket and client socket program. first i get some real certificate and then i used the first code to generate keystore for it. then i wrote server and client code so my server use that keystore as server certificate but no certificate sent during connection and session.getLocalCertificates() only return null
my keystore generating code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.KeyStore;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
public class MainClass {
public static void main(String args[]) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List mylist = new ArrayList();
FileInputStream in = new FileInputStream("C:\\Users\\nima\\Downloads\\72315359_example.com.cert");
Certificate cr = cf.generateCertificate(in);
mylist.add(cr);
CertPath cp = cf.generateCertPath(mylist);
System.out.println(cp);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
List cplist = cp.getCertificates();
Object[] o = cplist.toArray();
for (int i = 0; i < o.length; i++) {
X509Certificate c = (X509Certificate) o[i];
ks.setCertificateEntry("my" + i, c);
}
FileOutputStream output = new FileOutputStream("C:\\Users\\nima\\Downloads\\test.dat");
ks.store(output, "mypass".toCharArray());
output.close();
}
}
my server code:
import java.io.PrintStream;
import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
public class MainClass {
public static void main(String args[]) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\nima\\Downloads\\test.dat");
System.setProperty("javax.net.ssl.keyStorePassword", "mypass");
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket ss = ssf.createServerSocket(5432);
while (true) {
Socket s = ss.accept();
SSLSession session = ((SSLSocket) s).getSession();
Certificate[] cchain2 = session.getLocalCertificates();
for (int i = 0; i < cchain2.length; i++) {
System.out.println(((X509Certificate) cchain2[i]).getSubjectDN());
}
System.out.println("Peer host is " + session.getPeerHost());
System.out.println("Cipher is " + session.getCipherSuite());
System.out.println("Protocol is " + session.getProtocol());
System.out.println("ID is " + new BigInteger(session.getId()));
System.out.println("Session created in " + session.getCreationTime());
System.out.println("Session accessed in " + session.getLastAccessedTime());
PrintStream out = new PrintStream(s.getOutputStream());
out.println("Hi");
out.close();
s.close();
}
}
}
my client code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class MainClass {
public static void main(String args[]) throws Exception {
System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\nima\\Downloads\\test.dat");
SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket s = ssf.createSocket("127.0.0.1", 5432);
SSLSession session = ((SSLSocket) s).getSession();
Certificate[] cchain = session.getPeerCertificates();
System.out.println("The Certificates used by peer");
for (int i = 0; i < cchain.length; i++) {
System.out.println(((X509Certificate) cchain[i]).getSubjectDN());
}
System.out.println("Peer host is " + session.getPeerHost());
System.out.println("Cipher is " + session.getCipherSuite());
System.out.println("Protocol is " + session.getProtocol());
System.out.println("ID is " + new BigInteger(session.getId()));
System.out.println("Session created in " + session.getCreationTime());
System.out.println("Session accessed in " + session.getLastAccessedTime());
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String x = in.readLine();
System.out.println(x);
in.close();
}
}
my server code is from here and in both server and client side i get null from getLocalCertificates. It's also possible that all of my code would be wrong.
(From comments, expanded slightly)
If SSLSocket.getSession() is called before the handshake is done, it tries to do it, but if the handshake fails getSession() swallows the exception and just returns a 'nullSession' object which doesn't have the data a real session object would. Either (1) set sysprop javax.net.debug=ssl (at startup, usually on commandline with -D) and look at what it logs to see what is wrong with your handshake or (2) explicitly call ((SSLSocket)s).startHandshake() (which in spite of the name actually runs the handshake to completion, successful or not) and see what it throws.
In particular if you use the keystore file created by the first code shown, that contains only a certificate (trustedCertEntry) NOT a privateKeyEntry (with both privatekey and certificate/chain) as is necessary and required for an SSL/TLS server to use any of the common and default-enabled suites; this error will usually manifest, somewhat confusingly, as a handshake failure with 'no cipher[suite] in common' or 'no cipher[suite] overlap'.
That second part (SSL/TLS server without a privatekey doesn't work) has been asked and answered many times, but I don't recall any dupes that also include the 'getSession masks the error' part.

javax.net.ssl.SSLException: unexpected_message

We're trying to make secure http communication between client an server.
The server provided the certificates, we took them, install them and we start running, the point is to exchange an exact number of messages simultaneously between the client and server consecutively, the problem that's driving us crazy is that between the requests, at SSLHANDSHAKE we get randomly the exception javax.net.ssl.SSLException: Received fatal alert: unexpected_message exactly at ServerHello handshake phase, and i don't know how or why this is happening while it keeps working fine for 98% of the other requests.
it crashes at step 2.
Transporter.java : This is the class responsible for sending and receiving the data.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.KeyStore;
import java.util.ResourceBundle;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
public class Transporter {
private static ResourceBundle resource = ResourceBundle.getBundle("resourece_00");
private static final String keystore = resource.getString("server_keystore");
private static final String truststore = resource.getString("server_truststore");
private static final String keypass = resource.getString("server_keystore_pwd");
private static final String trustpass = resource.getString("server_truststore_pwd");
// secure channel variables
private static SSLSocketFactory sslSocketFactory = null;
public Transporter() {
// setupSocketFactory();
}
static {
try {
String protocol = "TLS";
String type = "JKS";
String algorithm = KeyManagerFactory.getDefaultAlgorithm();
String trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
// create and initialize an SSLContext object
SSLContext sslContext = SSLContext.getInstance(protocol);
sslContext.init(getKeyManagers(type, algorithm), getTrustManagers(type, trustAlgorithm), null);
// obtain the SSLSocketFactory from the SSLContext
sslSocketFactory = sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
private static KeyStore getStore(String type, String filename, String pwd) throws Exception {
KeyStore ks = KeyStore.getInstance(type);
InputStream istream = null;
try {
File ksfile = new File(filename);
istream = new FileInputStream(ksfile);
ks.load(istream, pwd != null ? pwd.toCharArray() : null);
} finally {
if (istream != null) {
istream.close();
}
}
return ks;
}
private static KeyManager[] getKeyManagers(String type, String algorithm) throws Exception {
KeyStore ks = getStore(type, keystore, keypass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, keypass.toCharArray());
return kmf.getKeyManagers();
}
private static TrustManager[] getTrustManagers(String type, String algorithm) throws Exception {
KeyStore ts = getStore(type, truststore, trustpass);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
tmf.init(ts);
return tmf.getTrustManagers();
}
public String sendToVD(String msg, String urll, Long timeOut) {
byte[] bytes = msg.getBytes();
HttpsURLConnection sconn = null;
URL url = null;
OutputStream out = null;
BufferedReader read = null;
String recu = null;
try {
url = new URL(urll);
sconn = (HttpsURLConnection) url.openConnection();
sconn.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession sslSession) {
return true;
}
});
sconn.setSSLSocketFactory(sslSocketFactory);
// sconn.setReadTimeout((timeOut.intValue()) * 1000);// set timeout
sconn.setRequestMethod("POST");
sconn.addRequestProperty("Content-Length", "" + bytes.length);
sconn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
sconn.setDoOutput(true);
sconn.setDoInput(true);
// send POST data
// This is the crash location
out = sconn.getOutputStream();
// OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
out.write(bytes);
out.flush();
// logger.info("flush!!!!!!!!!!!!!");
// out.close();
read = new BufferedReader(new InputStreamReader(sconn.getInputStream()));
String query = null;
recu = read.readLine();
while ((query = read.readLine()) != null) {
recu += query;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// close all connections here
if (out != null)
out.close();
if (read != null)
read.close();
if (sconn != null)
sconn.disconnect();
} catch (Exception ce) {
}
}
return recu;
}
}
The function sendToVD() does the main work of the exchange between the client and the server.
At Client-End :
A web application with JSF managing the front layer, spring managing the beans life cycle, the communication entry to the client is assured by Servlets.
The client is deployed in a RedHat Linux machine, all TLS_VERSIONS are enbaled, JDK_8.
At Server-Side: i can't post the detailed information about the target URL for security measures, but it follows the following pattern https://ip:port/path, and it supports TLS_v1.2.
Hope you can help me out.

Creation of an HTTPS server in Java

I have been trying to create a simple HTTPS server in my application. I am able to get the server running while also finishing the 'SSL context creation' without errors( where I have included the System.out.println("SSL context created ...\n");).
However, I am unable to connect to it through a browser or even a java written client. a java written client returns a NoHttpResponseException when I attempt to connect to this application.
" Exception in thread "main" org.apache.http.NoHttpResponseException: localhost:8000 failed to respond "
So, is it possible to point out what I am missing in the below code? Thanks
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManagerFactory;
public class HTTPSserver {
public static void main(String[] args) throws Exception {
char[] password = "SSLauthentication".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fileInput = new FileInputStream("C:\\Files\\Certificates\\clientkeystore");
ks.load(fileInput, password);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext ssl = SSLContext.getInstance("TLS");
ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
HttpsServer server = HttpsServer.create(new InetSocketAddress(8000), 0);
server.setHttpsConfigurator (new HttpsConfigurator(ssl)
{
#Override
public void configure (HttpsParameters params)
{
try
{
SSLContext c = getSSLContext();
SSLParameters sslparams = c.getDefaultSSLParameters();
params.setSSLParameters(sslparams);
System.out.println("SSL context created ...\n");
}
catch(Exception e2)
{
System.out.println("Invalid parameter ...\n");
e2.printStackTrace();
}
}
});
server.createContext("/test", new MyHandler());
server.setExecutor(null);
server.start();
}
static class MyHandler implements HttpHandler {
#Override
public void handle(HttpExchange HTTPmessage) throws IOException {
if("GET".equals(HTTPmessage.getRequestMethod()))
{
String response = "This is aaa response";
HTTPmessage.sendResponseHeaders(200, response.length());
OutputStream os = HTTPmessage.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
}

Data is not getting transferred between client and server using SSL

this is my server code
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class SSLServer {
final static String pathToStores = "C:/Users/Amee";
final static String keyStoreFile = "server.jks";
final static String passwd = "changeit";
final static int theServerPort = 8443;
static boolean debug = false;
public static void main(String args[]) throws Exception {
String trustFilename = pathToStores + "/" + keyStoreFile;
// System.out.println("Verifying KeyStore File of Client..");
System.setProperty("javax.net.ssl.keyStore", trustFilename);
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
if (debug)
System.setProperty("javax.net.debug", "all");
System.out.println("Setting up SSL parameters");
// Initialize socket connection
SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory
.getDefault();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf
.createServerSocket(theServerPort);
System.out.println("Server Started..Waiting for clients");
//sslServerSocket.setNeedClientAuth(true);
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
// sslSocket.startHandshake();
System.out.println("Client Connected!");
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
final int RSAKeySize = 1024;
final String newline = "\n";
Key pubKey = null;
Key privKey = null;
boolean flag = sslSocket.getNeedClientAuth();
System.out.println("Flag value: " + flag);
String messgae = "Hello Client!";
sslOS.write(messgae.getBytes());
// sslOS.close();
}
}
=================================================================
this is my client code
=============================================
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class SSLClient{
final static String pathToStores = "C:/Users/Amee";
final static String trustStoreFile = "client.jks";
final static String passwd = "changeit";
final static String theServerName = "localhost";
final static int theServerPort = 8443;
static boolean debug = false;
public static void main(String args[]) throws Exception {
String trustFilename = pathToStores + "/" + trustStoreFile;
System.out.println("Validating KeyStore file of Server..");
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
if (debug)
System.setProperty("javax.net.debug", "all");
SSLSocketFactory sslssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)sslssf.createSocket(theServerName, 8443);
System.out.println("Connected to Server!");
while (true) {
if (sslSocket.getInputStream().available() > 0) {
byte[] data = new byte[sslSocket.getInputStream().available()];
sslSocket.getInputStream().read(data);
System.out.println(new String(data));
}
}
}
}
================================================================
Give some suggestions...How would i be able to transfer the data over channel?
The way you are using available() is specifically warned against in the Javadoc. Use a fixed size buffer, and block in the read() method.

Categories

Resources