Hello everyone, I encountered a android ssl issue. I want to developer a android app, it can connect https web site through TLS tunnel proxy, but I failed. I tried to use several version httpclient or java socked api. I got the same error, but I it works find on my PC. I got the following error in android. I don't know why. Could you please help me? I attached the source file and a tcpdump file. In tcpdump file frame 27 is the alert type.
javax.net.ssl.SSLHandshakeException: Handshake failed
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:396)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.jason.httpclientexample.SSLSocketClientWithTunneling.doIt(SSLSocketClientWithTunneling.java:96)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.jason.httpclientexample.MainActivity.executeHttpRequest(MainActivity.java:100)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.jason.httpclientexample.MainActivity.access$100(MainActivity.java:24)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.jason.httpclientexample.MainActivity$2$1.run(MainActivity.java:61)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
java.lang.Thread.run(Thread.java:818)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err:
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted:
ssl=0x7fa87388a700: Failure in SSL library, usually a protocol error
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err:
error:100c50f5:SSL routines:ssl3_read_bytes:UNKNOWN_ALERT_TYPE
(external/boringssl/src/ssl/s3_pkt.c:980 0x7fa87bff2c9a:0x00000000)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err: at
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
03-16 19:26:46.290 11284-11379/com.jason.httpclientexample W/System.err:
... 5 more
Thanks,
John
--
You received this message because you are subscribed to the Google Groups
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/android-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/android-developers/048baa79-5f2a-476b-bda7-4ec0f2787974%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
package com.jason.httpclientexample;
/**
* Created by jbai on 3/16/16.
*/
import java.net.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.*;
import javax.net.ssl.*;
public class SSLSocketClientWithTunneling {
public static void main(String[] args) throws Exception {
new SSLSocketClientWithTunneling().doIt("172.16.50.50", 443);
}
String tunnelHost;
int tunnelPort;
public void doIt(String host, int port) {
try {
/*
* Let's setup the SSLContext first, as there's a lot of
* computations to be done. If the socket were created
* before the SSLContext, the server/proxy might timeout
* waiting for the client to actually send something.
*/
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
};
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory factory = ctx.getSocketFactory();
/*
* Set up a socket to do tunneling through the proxy.
* Start it off as a regular socket, then layer SSL
* over the top of it.
*/
//tunnelHost = System.getProperty("https.proxyHost");
//tunnelPort = Integer.getInteger("https.proxyPort").intValue();
tunnelHost = "172.16.50.51";
tunnelPort = 443;
//Socket tunnel = new Socket(tunnelHost, tunnelPort);
SSLSocket tunnel = (SSLSocket)factory.createSocket(tunnelHost, tunnelPort);
doTunnelHandshake(tunnel, host, port);
/*
* Ok, let's overlay the tunnel socket with SSL.
*/
SSLSocket socket = (SSLSocket)factory.createSocket(tunnel, host, port, true);
/*
* register a callback for handshaking completion event
*/
socket.addHandshakeCompletedListener(
new HandshakeCompletedListener() {
public void handshakeCompleted(
HandshakeCompletedEvent event) {
System.out.println("Handshake finished!");
System.out.println(
"\t CipherSuite:" + event.getCipherSuite());
System.out.println(
"\t SessionId " + event.getSession());
System.out.println(
"\t PeerHost " + event.getSession().getPeerHost());
}
}
);
/*
* send http request
*
* See SSLSocketClient.java for more information about why
* there is a forced handshake here when using PrintWriters.
*/
socket.startHandshake();
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())));
out.println("GET / HTTP/1.0");
out.println();
out.flush();
/*
* Make sure there were no surprises
*/
if (out.checkError())
System.out.println(
"SSLSocketClient: java.io.PrintWriter error");
/* read response */
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
out.close();
socket.close();
tunnel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Tell our tunnel where we want to CONNECT, and look for the
* right reply. Throw IOException if anything goes wrong.
*/
private void doTunnelHandshake(Socket tunnel, String host, int port)
throws IOException
{
OutputStream out = tunnel.getOutputStream();
String msg = "CONNECT " + host + ":" + port + " HTTP/1.1\n"
+ "User-Agent: "
+ "java"
+ "\r\n\r\n";
byte b[];
try {
/*
* We really do want ASCII7 -- the http protocol doesn't change
* with locale.
*/
b = msg.getBytes("ASCII7");
} catch (UnsupportedEncodingException ignored) {
/*
* If ASCII7 isn't there, something serious is wrong, but
* Paranoia Is Good (tm)
*/
b = msg.getBytes();
}
out.write(b);
out.flush();
/*
* We need to store the reply so we can create a detailed
* error message to the user.
*/
byte reply[] = new byte[200];
int replyLen = 0;
int newlinesSeen = 0;
boolean headerDone = false; /* Done on first newline */
InputStream in = tunnel.getInputStream();
boolean error = false;
while (newlinesSeen < 2) {
int i = in.read();
if (i < 0) {
throw new IOException("Unexpected EOF from proxy");
}
if (i == '\n') {
headerDone = true;
++newlinesSeen;
} else if (i != '\r') {
newlinesSeen = 0;
if (!headerDone && replyLen < reply.length) {
reply[replyLen++] = (byte) i;
}
}
}
/*
* Converting the byte array to a string is slightly wasteful
* in the case where the connection was successful, but it's
* insignificant compared to the network overhead.
*/
String replyStr;
try {
replyStr = new String(reply, 0, replyLen, "ASCII7");
} catch (UnsupportedEncodingException ignored) {
replyStr = new String(reply, 0, replyLen);
}
/* We asked for HTTP/1.0, so we should get that back */
if (!replyStr.startsWith("HTTP/1.1 200")) {
throw new IOException("Unable to tunnel through "
+ tunnelHost + ":" + tunnelPort
+ ". Proxy returns \"" + replyStr + "\"");
}
/* tunneling Handshake was successful! */
}
}
2.cap
Description: application/cap

