Android - 使用Let的加密证书https连接

时间:2017-06-11 11:42:00

标签: android post https ssl-certificate

我尝试使用HTTPS连接到我的远程服务器。我正在使用“Let's Encrypt”的证书。 我正在调用的php文件回声“成功” 我使用developer.android.com中的以下代码来信任CA:

public class VerifyKey extends AsyncTask<Void, Void, Void> {

    public static final String CERTIFICATE_TYPE_X_509 = "X.509";
    public static final String CERTIFICATE_ALIAS = "domain_name";
    public static final String SERVER_URL = "https://domain_name";

    Context mContext;

    public VerifyKey(Context c)
    {
        mContext=c;
    }

    @Override
    protected Void doInBackground(Void... params) {
        try
        {
            // Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
            InputStream caInput = mContext.getResources().openRawResource(R.raw.ca);
            Certificate ca;
            try {
                ca = cf.generateCertificate(caInput);
                Log.d("CONN_TEST_SSL","ca=" + ((X509Certificate) ca).getSubjectDN());

            } finally {
                caInput.close();
            }

// Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            MainActivity.tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            MainActivity.tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
            MainActivity.ssl_context = SSLContext.getInstance("TLS");
            MainActivity.ssl_context.init(null, MainActivity.tmf.getTrustManagers(), null);

// Tell the URLConnection to use a SocketFactory from our SSLContext
            URL url = new URL("https://domain_name/register.php");
            HttpsURLConnection urlConnection =
                    (HttpsURLConnection)url.openConnection();
            urlConnection.setSSLSocketFactory(MainActivity.ssl_context.getSocketFactory());
            InputStream in = urlConnection.getInputStream();

            BufferedReader br=new BufferedReader(new InputStreamReader(in));

            Log.d("CONN_TEST_SSL",br.readLine());
        }
        catch(Exception ex)
        {
            Log.d("CONN_TEST_SSL", "Problem", ex);
        }

        return null;
    }
}

对于我得到的第一个日志(getSubjectDN()):

ca=CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US

对于测试网址,我获得了“成功”

如您所见,我在MainActivity上为TrustManagerFactory和SSLContext声明了静态变量

现在,当我实施另一个课程时,事情发生了变化:

public class AuthServerInterface extends AsyncTask<String, Void, String> {


    String resp;
    private Context cont;
    private int myflag;

    public AsyncResponse del;

    public AuthServerInterface(Context context,AsyncResponse mydel,int flag) {
        this.cont = context;
        this.del=mydel;
        resp=new String("");
        this.myflag=flag;
    }


    protected void onPreExecute(){
    }

    @Override
    protected String doInBackground(String... arg0) {

        String msg="";

        if(myflag==0)
        {
            try {
                String fname = (String)arg0[0];
                String lname = (String)arg0[1];
                String mail_id = (String)arg0[2];
                String phone_no = (String)arg0[3];

                String link = MainActivity.BASE_DOMAIN + "register.php";

                String data = URLEncoder.encode("fname", "UTF-8") + "=" +
                        URLEncoder.encode(fname, "UTF-8");

                data+="&"+URLEncoder.encode("lname", "UTF-8") + "=" +
                        URLEncoder.encode(lname, "UTF-8");

                data+="&"+URLEncoder.encode("mail_id", "UTF-8") + "=" +
                        URLEncoder.encode(mail_id, "UTF-8");

                data+="&"+URLEncoder.encode("phone_no", "UTF-8") + "=" +
                        URLEncoder.encode(phone_no, "UTF-8");

                Log.d(data,"CONN_TEST");

                URL url = new URL(link);

                /////////////

                HttpsURLConnection conn =
                        (HttpsURLConnection)url.openConnection();
                conn.setSSLSocketFactory(MainActivity.ssl_context.getSocketFactory());
                /////////////

                conn.setDoOutput(true);
                OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

                wr.write(data);
                wr.flush();

                BufferedReader reader = new BufferedReader(new
                        InputStreamReader(conn.getInputStream()));

                StringBuilder sb = new StringBuilder();
                String line = null;

                // Read Server Response
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                    break;
                }
                msg=sb.toString();
            } catch (Exception e) {

                msg= new String("Exception: " + e.getMessage());
            }
        }

        return msg;

    }

    @Override
    protected void onPostExecute(String result){
        del.processFinish(result);
    }

...并按如下方式调用它们:

VerifyKey vk=new VerifyKey(getBaseContext());
                vk.execute();

                AuthServerInterface SI=new AuthServerInterface(getBaseContext(), new AsyncResponse() {
                    @Override
                    public void processFinish(String output) {

                        Log.d(output," CONN_TEST_REAL");

                    }
                },0);

                SI.execute(first_name,last_name,mail_id,phone_no);

验证部分工作正常。但是对于第二部分......

[ 06-11 16:48:44.093  2725: 2725 D/Exception: Hostname domain_name not verified:
                                                                                                                   certificate: sha1/xItPZS3lzfY8syDdUhT CONN_TEST_REAL

我是Android上的新手。什么可能出错?

1 个答案:

答案 0 :(得分:1)

嗯,我自己想出来了。

我在MainActivity中提供的BASE_DOMAIN字符串有&#34; www&#34;!

最小的事情可能会导致最大的问题