Android 中使用https
Posted conker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = backForData; if (HTTPSUtils.client == null) { HTTPSUtils.getInstance(context); } this.client = HTTPSUtils.client; } public ExChange(CallBackForData backForData) { _backForData = backForData; this.client = HTTPSUtils.client; } public void run(String encryptStr) throws Exception { mCrypt = new MCrypt(); Request request = new Request.Builder() .url("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 = response.body().string(); com.android.pgb.Utils.Log.e("_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的主要内容,如果未能解决你的问题,请参考以下文章
在 android 首选项片段中使用 startService()
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情