2016-03-21 22 views
0

Android aygıt (istemci) ile C# Server ile yuva bağlamaya çalışıyorum. İmzalı sertifika kullanıyorum.C# sunucusuna bağlanan Java istemcisi SSL

Makineler birbirlerini görebilir ve güvenli bir bağlantı kurmaya çalışır. Android'de bunun dışında bir hata alıyorum.

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 

Bu hatayı gidermek için bir çözüm sağlayabilirmiyim. Ya da bir örnekle bağlantı kurarak bunu mümkün kılan istemci ve/veya sunucu tarafı kütüphanesi, çünkü internette, soket kullanarak doğru SSL bağlantısının nasıl yapılacağı hakkında bilgi verilmediğinden. O 2.

Bu arasındaki bağlantı kurmak için kullanıyorum

Kod sunucusunun sürümünü basitleştirilmiş

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

DataStream sınıfına

Şimdi basitleştirilmiş istemci
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

cevap

0

anwser bu hata için biraz garip ama sonunda ben bunu düzeltmek için yönetmek.

Sorun C# DataStream sınıfı cadı kullanılan soketindeydi. Bunun yerine, istemciden Yaz ve Oku verilerine SSLStream kullanmalıyım. Ben bir BinaryWriter ve BinaryReader kullanmak yerine, IO'yu kendi başlarına yönetmeye çalışan herkes için yaygın bir hata olabileceğini düşünüyorum.

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