2016-03-21 174 views
0

我想連接Android設備(客戶端)與C#服務器與套接字。我正在使用簽名證書。Java客戶端連接到C#服務器SSL

機器可以看到對方並嘗試建立安全連接。 除了在Android上我得到休耕錯誤。

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 

你能否提供一個解決方案來解決這個錯誤。或者將客戶端和/或服務器端庫用於鏈接到一個示例,因爲互聯網上沒有足夠的信息如何使用套接字進行正確的SSL連接。我使用,使那些2

這之間的連接

代碼被簡化服務器的版本

//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); 
} 

的Android API 23

C#.NET 4.5

回答

0

的anwser是該錯誤位奇怪,但在最後,我管理解決它。

問題出在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; 
} 
相關問題