Java client connecting to C# server SSL

0

I'm trying to connect Android device (client) with C# Server with sockets. I'm using signed certificate.

The machines can see each others and tries to make a safe connection. Except that on Android I'm getting fallowing error.

javax.net.ssl.SSLProtocolException: Read error: ssl=0xa1f1c840: Failure in SSL library, usually a protocol error
error:100bd10c:SSL routines:ssl3_get_record:WRONG_VERSION_NUMBER (external/boringssl/src/ssl/s3_pkt.c:305 0xabf3fd97:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:705)
...rest of stack trace

Can you provide my with a solution to solve this error. Or to client and/or server side library that will make that possible with link to an example, since there are not enought information on the internet how to do proper SSL connection using sockets.

Code I'm using to make connection between those 2.

This is simplified version of server

//Server start
X509Certificate2 cert = new X509Certificate2(cert, pass);
TcpListener server = new TcpListener(ip, port);
server.Start();
while (running)
        {
            TcpClient tcpClient = server.AcceptTcpClient();
            Client client = new Client(this, tcpClient);
            //In constructor I'm starting a new thread with method below
        }

//Method mentioned above
void SetupConn()
{
       NetworkStream netStream = client.GetStream();
       SslStream ssl = new SslStream(netStream, false);
       ssl.AuthenticateAsServer(prog.cert, false, SslProtocols.Tls, true);
       dataStream = new DataStream(client.Client);
       dataStream.Write("2012");
       int hello = dataStream.ReadString();
       ... //Handling connection
}

//DataStream class
public DataStream(Socket clientSocket)
{
    _clientSocket = clientSocket;
}
public void Write(string message)
{
    int toSendLen = Encoding.ASCII.GetByteCount(message);
    byte[] toSendBytes = Encoding.ASCII.GetBytes(message);
    byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
    _clientSocket.Send(toSendLenBytes);
    _clientSocket.Send(toSendBytes);
}
public String ReadString()
{
    byte[] rcvLenBytes = new byte[4];
    _clientSocket.Receive(rcvLenBytes);
    int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
    byte[] rcvBytes = new byte[rcvLen];
    _clientSocket.Receive(rcvBytes);
    var ascii = Encoding.ASCII.GetString(rcvBytes);
    return ascii;
}

Now simplified client in android

SSLSocketFactory factory=(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket=(SSLSocket) factory.createSocket(ip, port);
DataStream stream = new DataStream(socket);
Log.v("Log",stream.ReadString() + "");
stream.Write("2012");

DataStream class

public void Write(String message) {
    byte[] toSendBytes = message.getBytes();
    int toSendLen = toSendBytes.length;
    byte[] toSendLenBytes = new byte[4];
    toSendLenBytes[0] = (byte) (toSendLen & 0xff);
    toSendLenBytes[1] = (byte) ((toSendLen >> 8) & 0xff);
    toSendLenBytes[2] = (byte) ((toSendLen >> 16) & 0xff);
    toSendLenBytes[3] = (byte) ((toSendLen >> 24) & 0xff);
    try {
        os.write(toSendLenBytes);
        os.write(toSendBytes);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public String ReadString() {
    byte[] lenBytes = new byte[4];
    try {
        is.read(lenBytes, 0, 4);
    } catch (IOException e) {
        e.printStackTrace();
    }
    int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
            ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
    byte[] receivedBytes = new byte[len];
    try {
        is.read(receivedBytes, 0, len);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new String(receivedBytes, 0, len);
}

Android API 23

C# .Net 4.5

java
c#
android
sockets
ssl
asked on Stack Overflow Mar 21, 2016 by Tomasz Juszczak • edited Mar 21, 2016 by Tomasz Juszczak

1 Answer

0

The anwser is a bit wierd for this error but in the end i manage to fix it.

The problem was in C# DataStream class witch used socket. Instead I should use SSLStream to Write and Read data from client. I think this may be a common mistake for everyone who tries to manage IO on their own, instead of using a BinaryWriter and BinaryReader.

SSLStream _clientSocket;
//DataStream class
public DataStream(SSLStream clientSocket)
{
    _clientSocket = clientSocket;
}
public void Write(string message)
{
    int toSendLen = Encoding.ASCII.GetByteCount(message);
    byte[] toSendBytes = Encoding.ASCII.GetBytes(message);
    byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
    _clientSocket.Write(toSendLenBytes);
    _clientSocket.Write(toSendBytes);
}
public String ReadString()
{
    byte[] rcvLenBytes = new byte[4];
    _clientSocket.Read(rcvLenBytes, 0 , 4);
    int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
    byte[] rcvBytes = new byte[rcvLen];
    _clientSocket.Read(rcvBytes, 0, rcvLen);
    var ascii = Encoding.ASCII.GetString(rcvBytes);
    return ascii;
}
answered on Stack Overflow Mar 22, 2016 by Tomasz Juszczak

User contributions licensed under CC BY-SA 3.0