【问题标题】:why do I get SSLProtocolExcepetion: Handshake failed when trying to send http request?为什么我在尝试发送 http 请求时收到 SSLProtocolExcepetion: Handshake failed ?
【发布时间】:2020-10-08 22:27:57
【问题描述】:

我试图将JSON 对象从android 发送到我在NodeJS 中编写的服务器。 服务器正在运行和工作,我可以使用Postman 软件对其进行POST。 但是当我尝试使用 android 发送JSON 时,我得到了SSLProtocolException: SSL handshake aborted

完整的日志:

javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xd7a38728: Failure in SSL library, usually a protocol error error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER (third_party/openssl/boringssl/src/ssl/tls_record.cc:242 0xbc4ddce6:0x00000000)

我使用此处的代码尝试发送 http 请求: How To Send json Object to the server from my android app

在我得到SSLProtocolException 之后,我尝试了这个解决方案:

  1. SSLSocket exception handshake error when trying to send to SSLServerSocket

  2. Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: Failure in SSL library, usually a protocol error

  3. javax.net.ssl.SSLException: SSL handshake aborted on android old devices

但似乎没有任何效果。

我在 localhost 上运行,但它说有一次我无法连接到本地主机,这就是为什么我在下面的代码中更改了 url。

我的代码:

public class SendProductJsonTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
    String data = "";

    HttpURLConnection httpURLConnection = null;
    try {
        httpURLConnection = (HttpURLConnection) new URL(strings[0]).openConnection();
        httpURLConnection.setRequestMethod("POST");

        httpURLConnection.setDoOutput(true);

        DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
        wr.writeBytes("PostData="+strings[1]);
        wr.flush();
        wr.close();

        InputStream in = httpURLConnection.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(in);

        int inputStreamData = inputStreamReader.read();

        while (inputStreamData != -1) {

            char current = (char) inputStreamData;

            inputStreamData = inputStreamReader.read();

            data += current;

        }

    } catch (Exception e) {
        Log.d("ccb", "doInBackground16: "+e.getCause());
        Log.d("ccb", "doInBackground17: "+e.getMessage());
        e.printStackTrace();
    } finally {
        if (httpURLConnection != null) {
            httpURLConnection.disconnect();
        }
    }
    return data;
}

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.d("ccb", "onPostExecute: "+s);
}

}

我如何调用 http 请求:

findViewById(R.id.sendBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO: in a click it will gather all data from the user, turn it into a json object, and will send it to the DB;
                nameOfProduct = ((EditText)findViewById(R.id.etNameOfPr)).getText().toString();
                serialOfProduct = ((EditText)findViewById(R.id.etSerialOfPr)).getText().toString();
                priceOfProduct = ((EditText)findViewById(R.id.etPriceOfPr)).getText().toString();

                try {
                    productJson(nameOfProduct, serialOfProduct, priceOfProduct, getGenderRB(), uriList, getColorsCB(), getSizeCB(), new JSONMadeListener() {
                        @Override
                        public void onJSONMade(JSONObject object) {
                            try {
                                SSLContext.getInstance("TLSv1.2");
                            } catch (NoSuchAlgorithmException e) {
                                e.printStackTrace();
                            }
                            try {
                                ProviderInstaller.installIfNeeded(getApplicationContext());
                            } catch (GooglePlayServicesRepairableException e) {
                                e.printStackTrace();
                            } catch (GooglePlayServicesNotAvailableException e) {
                                e.printStackTrace();
                            }
                            new SendProductJsonTask().execute("https://10.0.2.2:4000/products/add",object.toString());
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }

【问题讨论】:

  • 不要在 HTTPS URL 中使用 IP 地址。这很可能会失败并解释您的问题,因为证书很可能不是用于 IP 地址而是用于名称,因此客户端完成的验证将失败。

标签: java android ssl


【解决方案1】:
... .execute("https://10.0.2.2:4000/products/add",object.toString());

我很确定您所做的一切都是用https:// 替换工作中的http://,并希望通过这种方式神奇地通过HTTPS 访问服务器。只有这不起作用:服务器实际上必须实施并正确设置 HTTPS,包括证书等。如果不这样做,您将得到如下内容:

... routines:OPENSSL_internal:WRONG_VERSION_NUMBER ...

这是因为服务器的纯 HTTP 响应(可能是关于无效请求的错误消息)被客户端盲目地解释为 HTTPS 响应。鉴于 HTTPS 响应在特定字节偏移处包含 TLS 版本号,客户端会盲目地将这些字节解释为 TLS 版本,然后抱怨不支持的 TLS 版本。

要确保您的服务器正确地提供 HTTPS,请尝试使用浏览器:如果它在那里不起作用,那么它可能在您的应用中也不起作用。

【讨论】:

  • 我遇到了http 的问题,但我将其改回http,我获得了与服务器的连接,但在android 中出现异常:W/System.err: java .io.FileNotFoundException: 10.0.2.2:4000/products/add 在 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:255)
  • @pythwan:这与您原来的问题完全不同。你原来的问题得到了回答。请就新问题提出新问题。
猜你喜欢
  • 1970-01-01
  • 2013-01-26
  • 2021-07-29
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多