Java客户端连接到C#服务器SSL

Java客户端连接到C#服务器SSL,java,c#,android,sockets,ssl,Java,C#,Android,Sockets,Ssl,我正在尝试将Android设备(客户端)与带有套接字的C#服务器连接起来。我正在使用签名证书 这些机器可以看到彼此,并试图建立安全连接。 除了在安卓系统上,我遇到了一个错误 javax.net.ssl.SSLProtocolException: Read error: ssl=0xa1f1c840: Failure in SSL library, usually a protocol error error:100bd10c:SSL routines:ssl3_get_record:WRONG_

我正在尝试将Android设备(客户端)与带有套接字的C#服务器连接起来。我正在使用签名证书

这些机器可以看到彼此,并试图建立安全连接。 除了在安卓系统上,我遇到了一个错误

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
你能为我提供一个解决这个错误的方法吗。或者连接到客户端和/或服务器端库,这将通过链接到示例实现,因为internet上没有足够的信息说明如何使用套接字进行正确的SSL连接

我用来连接这两个的代码

这是服务器的简化版本

//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;
}
现在简化了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");
数据流类

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);
}
公共无效写入(字符串消息){
byte[]toSendBytes=message.getBytes();
int-toSendLen=toSendBytes.length;
字节[]toSendLenBytes=新字节[4];
toSendLenBytes[0]=(字节)(toSendLen&0xff);
toSendLenBytes[1]=(字节)((toSendLen>>8)和0xff);
toSendLenBytes[2]=(字节)((toSendLen>>16)和0xff);
toSendLenBytes[3]=(字节)((toSendLen>>24)和0xff);
试一试{
操作系统写入(toSendLenBytes);
操作系统写入(toSendBytes);
}捕获(IOE异常){
e、 printStackTrace();
}
}
公共字符串ReadString(){
字节[]lenBytes=新字节[4];
试一试{
is.read(lenBytes,0,4);
}捕获(IOE异常){
e、 printStackTrace();
}

int len=((lenBytes[3]&0xff)对于这个错误,anwser有点奇怪,但最后我设法修复了它

问题出在使用socket的C#DataStream类中。相反,我应该使用SSLStream从客户端写入和读取数据。我认为这可能是每个试图自己管理IO而不是使用BinaryWriter和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;
}