开发者

Android: Problem exchanging messages with SSL

I have been trying to get a client to communicate with a server securely through SSL. I created my own self-signed certificates and it seems like that the client can connect to the server using the certificates, but the client never seems to be getting the response from the server. I tried printing the content-length which returns -1 and the actual content seems to be an empty string, although a simple HTML 'hello world' is expected.

What am I doing wrong?

Server:

public class SSLServer {
   public static void main(String[] args) {
      String ksName = "key.jks";
      char ksPass[] = "password".toCharArray();
      char ctPass[] = "password".toCharArray();
      try {
         KeyStore ks = KeyStore.getInstance("JKS");
         ks.load(new FileInputStream(ksName), ksPass);
         KeyM开发者_StackOverflow社区anagerFactory kmf = 
         KeyManagerFactory.getInstance("SunX509");

         kmf.init(ks, ctPass);
         SSLContext sc = SSLContext.getInstance("TLS");
         sc.init(kmf.getKeyManagers(), null, null);
         SSLServerSocketFactory ssf = sc.getServerSocketFactory();
         SSLServerSocket s 
            = (SSLServerSocket) ssf.createServerSocket(8888);
         System.out.println("Server started:");
         // Listening to the port
         SSLSocket c = (SSLSocket) s.accept();
         BufferedWriter w = new BufferedWriter(
            new OutputStreamWriter(c.getOutputStream()));

         w.write("HTTP/1.0 200 OK");
         w.write("Content-Type: text/html");
         w.write("<html><body>Hello world!</body></html>");
         w.flush();
         w.close();
         c.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

}

Client:

public class TestSSLActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Instantiate the custom HttpClient
        DefaultHttpClient client = new MyHttpClient(getApplicationContext());
        HttpGet get = new HttpGet("https://192.168.15.195:8888");
        // Execute the GET call and obtain the response
        HttpResponse getResponse;
        try {
            getResponse = client.execute(get);
            HttpEntity responseEntity = getResponse.getEntity();
            Log.i("Connection",responseEntity.getContentLength()+"");
            BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent(), "UTF-8"));
            StringBuilder builder = new StringBuilder();

            for (String line = null; (line = reader.readLine()) != null;) {
                builder.append(line).append("\n");
            } 
            Log.i("Connection","build: "+builder.toString());


        } catch (Exception e) {
            Log.i("Connection",e.getMessage());
        }
    }   

Custom HTTP client:

public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.key);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "password".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}


You might want to change the server code to read the request from the client before sending the response. It could be that the client is blocking (and then timing out?) waiting for the server to read the request.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜