首页 > 代码库 > Android 中使用https

Android 中使用https

去年ios开发强制使用https,而公司的ios 和android 都是使用同一个服务和域名,这样就要求android这边也要使用https 来作为请求。

网上找了很多方法,这里简单记录一下:

这里我是用的是OkHttp,google 最新的文档中虽然也支持了https,但还是okhttp用的方便。

首先我们要把ca颁发 的证书文件放置一份到本地,之后在装个箱

  1  public static OkHttpClient client;
  2      3 
  4     /**
  5      * 初始化HTTPS,添加信任证书
  6      * @param context
  7      */
  8     public static OkHttpClient getInstance(Context context) {
  9         Context mContext; mContext = context.getApplicationContext();
 10         X509TrustManager trustManager;
 11         SSLSocketFactory sslSocketFactory;
 12         final InputStream inputStream;
 13         if(client==null) {
 14             try {
 15                 inputStream = mContext.getAssets().open("ca.crt"); // 得到证书的输入流
 16                 try {
 17                     trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书
 18                     SSLContext sslContext = SSLContext.getInstance("TLS");
 19                     sslContext.init(null, new TrustManager[]{trustManager}, null);
 20                     sslSocketFactory = sslContext.getSocketFactory();
 21 
 22                 } catch (GeneralSecurityException e) {
 23                     throw new RuntimeException(e);
 24                 }
 25 
 26                 client = new OkHttpClient.Builder()
 27                         .sslSocketFactory(sslSocketFactory, trustManager)
 28                         .build();
 29 
 30 
 31             } catch (IOException e) {
 32                 e.printStackTrace();
 33             }
 34             return client;
 35         }
 36         else {
 37             System.out.println("现在是返回已经存在的实例");
 38             return client;
 39         }
 40     }
 41 
 42     
 43     /**
 44      * 以流的方式添加信任证书
 45      */
 46     /**
 47      * Returns a trust manager that trusts {@code certificates} and none other. HTTPS services whose
 48      * certificates have not been signed by these certificates will fail with a {@code
 49      * SSLHandshakeException}.
 50      * <p>
 51      * <p>This can be used to replace the host platform‘s built-in trusted certificates with a custom
 52      * set. This is useful in development where certificate authority-trusted certificates aren‘t
 53      * available. Or in production, to avoid reliance on third-party certificate authorities.
 54      * <p>
 55      * <p>
 56      * <h3>Warning: Customizing Trusted Certificates is Dangerous!</h3>
 57      * <p>
 58      * <p>Relying on your own trusted certificates limits your server team‘s ability to update their
 59      * TLS certificates. By installing a specific set of trusted certificates, you take on additional
 60      * operational complexity and limit your ability to migrate between certificate authorities. Do
 61      * not use custom trusted certificates in production without the blessing of your server‘s TLS
 62      * administrator.
 63      */
 64     public static X509TrustManager trustManagerForCertificates(InputStream in)
 65             throws GeneralSecurityException {
 66         CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
 67         Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
 68         if (certificates.isEmpty()) {
 69             throw new IllegalArgumentException("expected non-empty set of trusted certificates");
 70         }
 71 
 72         // Put the certificates a key store.
 73         char[] password = "password".toCharArray(); // Any password will work.
 74         KeyStore keyStore = newEmptyKeyStore(password);
 75         int index = 0;
 76         for (Certificate certificate : certificates) {
 77             String certificateAlias = Integer.toString(index++);
 78             keyStore.setCertificateEntry(certificateAlias, certificate);
 79         }
 80 
 81         // Use it to build an X509 trust manager.
 82         KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
 83                 KeyManagerFactory.getDefaultAlgorithm());
 84         keyManagerFactory.init(keyStore, password);
 85         TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
 86                 TrustManagerFactory.getDefaultAlgorithm());
 87         trustManagerFactory.init(keyStore);
 88         TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
 89         if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
 90             throw new IllegalStateException("Unexpected default trust managers:"
 91                     + Arrays.toString(trustManagers));
 92         }
 93         return (X509TrustManager) trustManagers[0];
 94     }
 95 
 96 
 97     /**
 98      * 添加password
 99      * @param password
100      * @return
101      * @throws GeneralSecurityException
102      */
103     public static KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
104         try {
105             KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); // 这里添加自定义的密码,默认
106             InputStream in = null; // By convention, ‘null‘ creates an empty key store.
107             keyStore.load(in, password);
108             return keyStore;
109         } catch (IOException e) {
110             throw new AssertionError(e);
111         }
112     }

这里简单的把构造https封装好,然后在单例出一个请求类

  private MCrypt mCrypt;
    public OkHttpClient client;
    private CallBackForData _backForData;
    private String encryptStr;
    private JSONObject jsonObj;
    public Integer userId = 0;
    private JSONObject jsonObjArr;

    public ExChange(CallBackForData backForData, Context context) {
        _backForData = http://www.mamicode.com/backForData;"https://www.xxx.com")
                .post(RequestBody.create(MediaType.parse("application/json"),
                        encryptStr
                )).build();


        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

                System.out.println("错误" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {


                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                Headers responseHeaders = response.headers();
                for (int i = 0; i < responseHeaders.size(); i++) {
                    System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
                }

                String Data = http://www.mamicode.com/response.body().string();"_backForData" + Thread.currentThread().getId());
                JSONObject obj = null;
                try {
                    obj = new JSONObject(Data);
                    JSONArray arr = JSONUtils.getJSONArray(obj, "data");
                    String cmd = JSONUtils.getString(obj, "cmd").toString();
                    int code = JSONUtils.getInt(obj, "code", 0);
                    if (_backForData != null)
                        _backForData.onMessage(Data, cmd, code);
                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        });
    }

    public interface CallBackForData {

        void onMessage(String str, String cmd, int code);

    }

}

 之后的页码数据都从这个类走就可以了。

  以上!

Android 中使用https