如何在Android客户端和Java服务器之间创建安全的SSL连接?

时间:2011-08-28 08:09:37

标签: java android security sockets ssl

我正在尝试在我的Android客户端和java服务器之间创建安全的TCP / IP连接。到目前为止的密码学不是我的强项。我知道我必须使用Bouncy Castle钥匙商,但我被卡住了。

我需要创建一个可以与服务器和客户端一起使用的自签名证书。这就是我被困住的地方。

         InputStream clientTruststoreIs = getResources().openRawResource(R.raw.bks);
         KeyStore trustStore = null;
         trustStore = KeyStore.getInstance("BKS");
         trustStore.load(clientTruststoreIs, "123456".toCharArray());
        InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
        SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();

        sslSocket = (SSLSocket) sslsocketfactory.createSocket(serverAddr, 2222);
        inputStream =  sslSocket.getInputStream();  
        Log.d("TEST", "\n1 input");

连接正常,它显示服务器端的连接,但是行inputStream = sslSocket.getInputStream()完全锁定/不返回。我不确定我是否正确设置了任何充气城堡,或者是否正确设置了服务器。请帮助,我在我的智慧结束....

编辑: 我修改了服务器,以便它在连接时发送数据,但仍然没有,我改变了输入和输出流的顺序,然后它锁定了我获取输出流的位置:

        sslSocket = (SSLSocket) sslsocketfactory.createSocket(serverAddr, 9999);
        outputStream = sslSocket.getOutputStream();
        Log.d("test", "--**--- created socket 2.0 outputsreams"); // does not reach here
        outputStreamWriter = new OutputStreamWriter(outputStream);
        bufferedWriter = new  BufferedWriter(outputStreamWriter);         
        inputStream =  sslSocket.getInputStream();  
        inputStreamReader = new InputStreamReader(inputStream);
        bufferedReader = new BufferedReader(inputStreamReader);
        ...
        String line = bufferedReader.readLine(); // where I'd expect it to lock...

所以仍然没有运气,没有超时,没有例外,只是等待那里......

3 个答案:

答案 0 :(得分:3)

我认为您的问题类似于this。 SSL套接字连接的工作流程相同:

  

但是,基本知识与此计划中的基本内容大致相同:

     

打开一个插座。

     

打开输入流并将输出流输出到套接字。

     

根据服务器的协议读取和写入流,在完成消息后调用流上的flush()。

     

关闭溪流。

     

关闭套接字。

所以你应该

  1. 首先通过从客户端flush写完服务器的OutputStream,向服务器发送请求。
  2. 然后,服务器将通过其InputStream接收消息,并可以返回写入其OutputStream,完成后再次刷新。
  3. 使用InputStream从客户端读取响应,从1开始直到完成。
  4. 最后,你应该关闭所有流。

    在尝试在客户端读取响应之前先刷新并发送请求应该会停止“挂起行为”。


    修改:您确定在服务器上使用SSLServerSocketFactory吗?您似乎正在尝试将SSLSocketFactory用于客户端服务器。那不行。我用Google搜索this tutorial,这与您的代码看起来基本类似。

答案 1 :(得分:1)

您可以尝试使用org.apache.http.conn.ssl.SSLSocketFactory类,特别是this constructor

编辑2017年3月26日:

忽略我上面写的内容,该类在Android上弃用Apache HTTP客户端时已被弃用。相反,Android会维护和增强标准HttpURLConnectionHttpsURLConnection类。请参阅this for a full explanation

答案 2 :(得分:0)

不确定您的代码是否符合预期。但行


    inputStream =  sslSocket.getInputStream();  

基本上是期望来自套接字的服务器响应。在大多数情况下,除非您首先请求某些内容(通过写入套接字输出流),否则请求响应将阻止套接字并等待。