当OkHttps遇到https请求
2016-11-22 17:42
197 查看
private static SSLSocketFactory getSocketFactory(List<InputStream> certificates) { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); try { for (int i = 0, size = certificates.size(); i < size; ) { InputStream certificate = certificates.get(i); String certificateAlias = Integer.toString(i++); keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); if (certificate != null) { certificate.close(); } } } catch (IOException e) { e.printStackTrace(); } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { e.printStackTrace(); } return null; }
自定义Application
@Override public void onCreate() { super.onCreate(); initHttpsCertificate(); }
import java.io. 4000 IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class RetrofitTools { // 证书数据 private static List<byte[]> CERTIFICATES_DATA = new ArrayList<byte[]>(); /** * 添加https证书 * * @param inputStream */ public synchronized static void addCertificate(InputStream inputStream) { if (inputStream != null) { try { int ava = 0;// 数据当次可读长度 int len = 0;// 数据总长度 ArrayList<byte[]> data = new ArrayList<byte[]>(); while ((ava = inputStream.available()) > 0) { byte[] buffer = new byte[ava]; inputStream.read(buffer); data.add(buffer); len += ava; } byte[] buff = new byte[len]; int dstPos = 0; for (byte[] bytes : data) { int length = bytes.length; System.arraycopy(bytes, 0, buff, dstPos, length); dstPos += length; } CERTIFICATES_DATA.add(buff); } catch (IOException e) { e.printStackTrace(); } } } /** * https证书 * * @return */ public static List<byte[]> getCertificatesData() { return CERTIFICATES_DATA; } }
private void initHttpsCertificate() { try { String[] certFiles = this.getAssets().list("certs"); if (certFiles != null) { for (String cert : certFiles) { InputStream is = getAssets().open("certs/" + cert); RetrofitTools.addCertificate(is); // 这里将证书读取出来,,放在配置中byte[]里 } } } catch (IOException ioe) { ioe.printStackTrace(); } }
// 添加证书 List<InputStream> certificates = new ArrayList<InputStream>(); List<byte[]> certs_data = RetrofitTools.getCertificatesData(); // 将字节数组转为数组输入流 if (certs_data != null && !certs_data.isEmpty()) { for (byte[] bytes : certs_data) { certificates.add(new ByteArrayInputStream(bytes)); } }
OkHttpClient.Builder builder = new OkHttpClient.Builder(); SSLSocketFactory sslSocketFactory = getSocketFactory(certificates); if (sslSocketFactory != null) { builder.socketFactory(sslSocketFactory); }
===========================================================================================================
/* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package okhttp3.recipes; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.util.Arrays; import java.util.Collection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import okhttp3.CertificatePinner; import okhttp3.Headers; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okio.Buffer; public final class CustomTrust { private final OkHttpClient client; public CustomTrust() { X509TrustManager trustManager; SSLSocketFactory sslSocketFactory; try { trustManager = trustManagerForCertificates(trustedCertificatesInputStream()); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { trustManager }, null); sslSocketFactory = sslContext.getSocketFactory(); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } client = new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManager) .build(); } public void run() throws Exception { Request request = new Request.Builder() .url("https://publicobject.com/helloworld.txt") .build(); try (Response response = client.newCall(request).execute()) { 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)); } System.out.println(response.body().string()); } } /** * Returns an input stream containing one or more certificate PEM files. This implementation just * embeds the PEM files in Java strings; most applications will instead read this from a resource * file that gets bundled with the application. */ private InputStream trustedCertificatesInputStream() { // PEM files for root certificates of Comodo and Entrust. These two CAs are sufficient to view // https://publicobject.com (Comodo) and https://squareup.com (Entrust). But they aren't // sufficient to connect to most HTTPS sites including https://godaddy.com and https://visa.com. // Typically developers will need to get a PEM file from their organization's TLS administrator. String comodoRsaCertificationAuthority = "" + "-----BEGIN CERTIFICATE-----\n" + "MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB\n" + "hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" + "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" + "BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5\n" + "MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" + "EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" + "Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh\n" + "dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR\n" + "6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X\n" + "pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC\n" + "9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV\n" + "/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf\n" + "Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z\n" + "+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w\n" + "qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah\n" + "SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC\n" + "u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf\n" + "Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq\n" + "crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\n" + "FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB\n" + "/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl\n" + "wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM\n" + "4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV\n" + "2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna\n" + "FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ\n" + "CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK\n" + "boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke\n" + "jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL\n" + "S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb\n" + "QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl\n" + "0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB\n" + "NVOFBkpdn627G190\n" + "-----END CERTIFICATE-----\n"; String entrustRootCertificateAuthority = "" + "-----BEGIN CERTIFICATE-----\n" + "MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC\n" + "VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0\n" + "Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW\n" + "KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl\n" + "cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw\n" + "NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw\n" + "NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy\n" + "ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV\n" + "BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ\n" + "KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo\n" + "Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4\n" + "4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9\n" + "KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI\n" + "rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi\n" + "94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB\n" + "sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi\n" + "gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo\n" + "kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE\n" + "vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\n" + "A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t\n" + "O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua\n" + "AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP\n" + "9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/\n" + "eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m\n" + "0vdXcDazv/wor3ElhVsT/h5/WrQ8\n" + "-----END CERTIFICATE-----\n"; return new Buffer() .writeUtf8(comodoRsaCertificationAuthority) .writeUtf8(entrustRootCertificateAuthority) .inputStream(); } /** * Returns a trust manager that trusts {@code certificates} and none other. HTTPS services whose * certificates have not been signed by these certificates will fail with a {@code * SSLHandshakeException}. * * <p>This can be used to replace the host platform's built-in trusted certificates with a custom * set. This is useful in development where certificate authority-trusted certificates aren't * available. Or in production, to avoid reliance on third-party certificate authorities. * * <p>See also {@link CertificatePinner}, which can limit trusted certificates while still using * the host platform's built-in trust store. * * <h3>Warning: Customizing Trusted Certificates is Dangerous!</h3> * * <p>Relying on your own trusted certificates limits your server team's ability to update their * TLS certificates. By installing a specific set of trusted certificates, you take on additional * operational complexity and limit your ability to migrate between certificate authorities. Do * not use custom trusted certificates in production without the blessing of your server's TLS * administrator. */ private X509TrustManager trustManagerForCertificates(InputStream in) throws GeneralSecurityException { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in); if (certificates.isEmpty()) { throw new IllegalArgumentException("expected non-empty set of trusted certificates"); } // Put the certificates a key store. char[] password = "password".toCharArray(); // Any password will work. KeyStore keyStore = newEmptyKeyStore(password); int index = 0; for (Certificate certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificate); } // Use it to build an X509 trust manager. KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, password); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); } return (X509TrustManager) trustManagers[0]; } private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream in = null; // By convention, 'null' creates an empty key store. keyStore.load(in, password); return keyStore; } catch (IOException e) { throw new AssertionError(e); } } public static void main(String... args) throws Exception { new CustomTrust().run(); } }
相关文章推荐
- Unrecognized SSL message, plaintext connection?https请求遇到异常分析
- AF https 请求遇到的坑
- 高效开发使用框架请求https(xutils3 Nohttp,OkhttpUtils(zhy))
- Python requests请求https遇到问题
- iOS开发工具-如何使用网络封包分析工具Charles,通过配置proxy对http、https、tcp、udp 等协议的请求响应过程交互信息进行分析、判断、解决我们移动开发中的遇到的各种实际问题。
- 开启Charles情况下requests 请求https遇到证书验证错误的解决方法
- android https——okhttp实现https请求
- Android-OKhttp解决https安全链接请求问题
- Unrecognized SSL message, plaintext connection?https请求遇到异常分析
- AFNetworking进行https请求遇到的错误和解决方式
- iOS https请求第一步从服务器下载证书
- android网络请求组件(一)OkHttp3的封装使用
- Volley封装,一行代码搞定http请求(重点介绍cookie、https、自定义requst请求)
- [置顶] OKRx+OkGo(okhttp-util升级版)网络请求框架使用
- 网络请求三方库——OkHttp
- https跨域请求jsonp以及else
- Android Retrofit2&OkHttp3添加统一的请求头Header
- Android使用Https请求,双向认证、app端配置
- https和http,IE7请求被拦截的问题解决
- Android Https相关完全解析 当OkHttp遇到Https