Android项目中使用HTTPS配置的步骤详解

前言

如果你的项目的网络框架是okhttp,那么使用https还是挺简单的,因为okhttp默认支持HTTPS。传送门

下面话不多说了,来一起看看详细的介绍:

Android 使用 HTTPS 配置的步骤。

1、step

配置hostnameVerifier

new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

return true;

}

};

2.step

配置 sslSocketFactory

public static SSLSocketFactory getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password){

try{

TrustManager[] trustManagers = prepareTrustManager(certificates);

KeyManager[] keyManagers = prepareKeyManager(bksFile, password);

SSLContext sslContext = SSLContext.getInstance("TLS");

TrustManager trustManager = null;

if (trustManagers != null){

trustManager = new MyTrustManager(chooseTrustManager(trustManagers));

} else{

trustManager = new UnSafeTrustManager();

}

sslContext.init(keyManagers, new TrustManager[]{trustManager}, new SecureRandom());

return sslContext.getSocketFactory();

} catch (NoSuchAlgorithmException e){

throw new AssertionError(e);

} catch (KeyManagementException e){

throw new AssertionError(e);

} catch (KeyStoreException e){

throw new AssertionError(e);

}

}

private class UnSafeHostnameVerifier implements HostnameVerifier{

@Override

public boolean verify(String hostname, SSLSession session){

return true;

}

}

private static class UnSafeTrustManager implements X509TrustManager{

@Override

public void checkClientTrusted(X509Certificate[] chain, String authType)throws CertificateException{}

@Override

public void checkServerTrusted(X509Certificate[] chain, String authType)throws CertificateException{}

@Override

public X509Certificate[] getAcceptedIssuers(){

return new X509Certificate[]{};

}

}

private static TrustManager[] prepareTrustManager(InputStream... certificates){

if (certificates == null || certificates.length <= 0) return null;

try{

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

keyStore.load(null);

int index = 0;

for (InputStream certificate : certificates){

String certificateAlias = Integer.toString(index++);

keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

try{

if (certificate != null)

certificate.close();

} catch (IOException e){

}

}

TrustManagerFactory trustManagerFactory = null;

trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

trustManagerFactory.init(keyStore);

TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

return trustManagers;

} catch (NoSuchAlgorithmException e){

e.printStackTrace();

} catch (CertificateException e){

e.printStackTrace();

} catch (KeyStoreException e){

e.printStackTrace();

} catch (Exception e){

e.printStackTrace();

}

return null;

}

private static KeyManager[] prepareKeyManager(InputStream bksFile, String password){

try{

if (bksFile == null || password == null) return null;

KeyStore clientKeyStore = KeyStore.getInstance("BKS");

clientKeyStore.load(bksFile, password.toCharArray());

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

keyManagerFactory.init(clientKeyStore, password.toCharArray());

return keyManagerFactory.getKeyManagers();

} catch (KeyStoreException e){

e.printStackTrace();

} catch (NoSuchAlgorithmException e){

e.printStackTrace();

} catch (UnrecoverableKeyException e){

e.printStackTrace();

} catch (CertificateException e){

e.printStackTrace();

} catch (IOException e){

e.printStackTrace();

} catch (Exception e){

e.printStackTrace();

}

return null;

}

private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers){

for (TrustManager trustManager : trustManagers){

if (trustManager instanceof X509TrustManager){

return (X509TrustManager) trustManager;

}

}

return null;

}

private static class MyTrustManager implements X509TrustManager{

private X509TrustManager defaultTrustManager;

private X509TrustManager localTrustManager;

public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException{

TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

var4.init((KeyStore) null);

defaultTrustManager = chooseTrustManager(var4.getTrustManagers());

this.localTrustManager = localTrustManager;

}

@Override

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException{}

@Override

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException{

try{

defaultTrustManager.checkServerTrusted(chain, authType);

} catch (CertificateException ce){

localTrustManager.checkServerTrusted(chain, authType);

}

}

@Override

public X509Certificate[] getAcceptedIssuers(){

return new X509Certificate[0];

}

}

调用 getSslSocketFactory(null,null,null) 即可。

3.step

设置OkhttpClient。

方法 getSslSocketFactory(null,null,null) 的第一个参数 本来要传入自签名证书的,当传入null 即可忽略自签名证书。

如果你想尝试不忽略自签名证书 你可以调用下面的方法获取 SSLSocketFactory。并设置到OkhttpClient中。

public static SSLSocketFactory getSSlFactory(Context context) {

try {

CertificateFactory cf = CertificateFactory.getInstance("X.509");

InputStream caInput = new BufferedInputStream(context.getAssets().open("client.cer"));//把证书打包在asset文件夹中

Certificate ca;

try {

ca = cf.generateCertificate(caInput);

LogUtil.d("Longer", "ca=" + ((X509Certificate) ca).getSubjectDN());

LogUtil.d("Longer", "key=" + ((X509Certificate) ca).getPublicKey());

} 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();

TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);

tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager

SSLContext s = SSLContext.getInstance("TLSv1", "AndroidOpenSSL");

s.init(null, tmf.getTrustManagers(), null);

return s.getSocketFactory();

} catch (CertificateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (KeyStoreException e) {

e.printStackTrace();

} catch (KeyManagementException e) {

e.printStackTrace();

} catch (NoSuchProviderException e) {

e.printStackTrace();

}

return null;

}

通过上面的几步配置即可使用https的自签名证书 和 单向验证的Https了。

Glide 访问Https的图片

1.step

在build.gradle 引入下面的aar

/提供的Module/

compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'

2.step

OkHttpClient okhttpClient = new OkHttpClient.Builder()

.connectTimeout(30, TimeUnit.SECONDS)

.retryOnConnectionFailure(true) //设置出现错误进行重新连接。

.connectTimeout(15, TimeUnit.SECONDS)

.readTimeout(60 * 1000, TimeUnit.MILLISECONDS)

.sslSocketFactory(HttpsUtils.getSslSocketFactory(null,null,null))

.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

return true;

}

})

.build();

//让Glide能用HTTPS

Glide.get(this).register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okhttpClient));

设置已经验证证书的的OkhttpClient 到Glide 既可。

总结

以上是 Android项目中使用HTTPS配置的步骤详解 的全部内容, 来源链接: utcz.com/z/333584.html

回到顶部