900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > :https web服务器ssl认证项目 Https自定义证书引入问题(2)

:https web服务器ssl认证项目 Https自定义证书引入问题(2)

时间:2023-01-22 04:39:14

相关推荐

:https web服务器ssl认证项目 Https自定义证书引入问题(2)

上一篇介绍接口使用https并且证书是自签的情况下,如何在客户端信任服务器证书,没有看过的请移步

1.Webview加载https问题

1.1 最简单的方式,助各位大佬一秒脱坑

自定义证书的https地址在加载时会进入

onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) 方法,前提是自定义webviewClient类。这时候调用 handler.proceed()即可。也就是忽略验证证书这个过程。

这个方式简单,快捷,但是可能会过不了大厂的安全监测,handler.proceed()这个方法会被监测到,视为https安全检测(本人就是被卡在这里,哭),另外在上架google应用时也会因此被拒,提示使用handler.cancel()方法,但是没有实际作用,因为会加载不出来。

1.2 安全的方式

安全的方式当然是让webview信任服务器证书了。

首先把证书放入项目中

za.cer https证书

private void handlerCer(final SslErrorHandler ssl, String url) {

OkHttpClient.Builder builder;

try {

builder = setCertificates1(new OkHttpClient.Builder(), context.getAssets().open("zs.cer"));

//builder=checkAction(new OkHttpClient.Builder());

}catch (Exception e) {

builder =new OkHttpClient.Builder();

}

builder.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

//忽略域名检查

return true;

}

});

Request request =new Request.Builder().url(url).build();

builder.build().newCall(request).enqueue(new okhttp3.Callback() {

@Override

public void onFailure(okhttp3.Call call, IOException e) {

ssl.cancel();

}

@Override

public void onResponse(okhttp3.Call call, okhttp3.Response response)throws IOException {

ssl.proceed();

}

});

}

private OkHttpClient.Builder setCertificates(OkHttpClient.Builder client, InputStream... certificates) {

try {

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

// KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");

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) {

}

}

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

TrustManagerFactory trustManagerFactory =

TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

trustManagerFactory.init(keyStore);

sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

X509TrustManager trustManager = Platform.get().trustManager(sslSocketFactory);

client.sslSocketFactory(sslSocketFactory, trustManager);

} catch (Exception e) {

e.printStackTrace();

}

return client;

}

还是在onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)调用这个方法。

重点这里我们需要验证最后是否有进入最后的onResponse方法,说明我们信任证书后访问网址响应成功,进入onFailures说明我们的证书有问题。注意在响应onReceivedSslError之前asLog信息中可以看到一个报错x509Util:.java.security.cert.CertPathValidatorException: Trust anchor for certification 就是这个让他进入sslError所以不必惊慌。但是这里我们依然少不了被安全检测扫描到proceed()

扫描到的漏洞

但是我们可以大声说我们已经信任了证书。

2 glide遇到使用自签证书的https图片链接

这里我们要用到GlideModule来进行网络请求库的定制,里面要重写两个方法

@Override

public void applyOptions(Context context, GlideBuilder builder) {

//通过builder.setXXX进行配置. 缓存配置,图片配置

}

@Override

public void registerComponents(Context context, Glide glide) {

//通过glide.register进行配置. 对网络上的配置做一些处理

}

2.1 拷贝’com.github.bumptech.glide:okhttp-integration:1.4.0@aar’里面3个类OkHttpGlideModule ,OkHttpUrlLoader,OkHttpStreamFetcher到项目中

先贴上后两个的代码,直接使用即可

OkHttpStreamFetcher

package com.example.appuser.testother.utils.https;

import com.bumptech.glide.Priority;

import com.bumptech.glide.load.data.DataFetcher;

import com.bumptech.glide.load.model.GlideUrl;

import com.bumptech.glide.util.ContentLengthInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Map;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

import okhttp3.ResponseBody;

/**

* Fetches an {@link InputStream} using the okhttp library.

*/

public class OkHttpStreamFetcher implements DataFetcher

{

private final OkHttpClient client;

private final GlideUrl url;

private InputStream stream;

private ResponseBody responseBody;

public OkHttpStreamFetcher(OkHttpClient client, GlideUrl url) {

this.client = client;

this.url = url;

}

@Override

public InputStream loadData(Priority priority) throws Exception

{

Request.Builder requestBuilder = new Request.Builder()

.url(url.toStringUrl());

for (Map.Entry headerEntry : url.getHeaders().entrySet()) {

String key = headerEntry.getKey();

requestBuilder.addHeader(key, headerEntry.getValue());

}

Request request = requestBuilder.build();

Response response = client.newCall(request).execute();

responseBody = response.body();

if (!response.isSuccessful()) {

throw new IOException("Request failed with code: " + response.code());

}

long contentLength = responseBody.contentLength();

stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);

return stream;

}

@Override

public void cleanup() {

if (stream != null) {

try {

stream.close();

} catch (IOException e) {

// Ignored

}

}

if (responseBody != null) {

responseBody.close();

}

}

@Override

public String getId() {

return url.getCacheKey();

}

@Override

public void cancel() {

// TODO: call cancel on the client when this method is called on a background thread. See #257

}

}

OkHttpUrlLoader

package com.example.appuser.testother.utils.https;

import android.content.Context;

import com.bumptech.glide.load.data.DataFetcher;

import com.bumptech.glide.load.model.GenericLoaderFactory;

import com.bumptech.glide.load.model.GlideUrl;

import com.bumptech.glide.load.model.ModelLoader;

import com.bumptech.glide.load.model.ModelLoaderFactory;

import java.io.InputStream;

import okhttp3.OkHttpClient;

public class OkHttpUrlLoader implements ModelLoader

{

/**

* The default factory for {@link OkHttpUrlLoader}s.

*/

public static class Factory implements ModelLoaderFactory

{

private static volatile OkHttpClient internalClient;

private OkHttpClient client;

private static OkHttpClient getInternalClient() {

if (internalClient == null) {

synchronized (Factory.class) {

if (internalClient == null) {

internalClient = new OkHttpClient();

}

}

}

return internalClient;

}

/**

* Constructor for a new Factory that runs requests using a static singleton client.

*/

public Factory() {

this(getInternalClient());

}

/**

* Constructor for a new Factory that runs requests using given client.

*/

public Factory(OkHttpClient client) {

this.client = client;

}

@Override

public ModelLoader build(Context context, GenericLoaderFactory factories) {

return new OkHttpUrlLoader(client);

}

@Override

public void teardown() {

// Do nothing, this instance doesn't own the client.

}

}

private final OkHttpClient client;

public OkHttpUrlLoader(OkHttpClient client) {

this.client = client;

}

@Override

public DataFetcher getResourceFetcher(GlideUrl model, int width, int height) {

return new OkHttpStreamFetcher(client, model);

}

}

OkHttpGlideModule

package com.alpha58.okhttps.https;

import android.content.Context;

import com.alpha58.okhttps.utils.HTTPSUtils;

import com.bumptech.glide.Glide;

import com.bumptech.glide.GlideBuilder;

import com.bumptech.glide.load.model.GlideUrl;

import com.bumptech.glide.module.GlideModule;

import java.io.InputStream;

/**

* A {@link GlideModule} implementation to replace Glide's default

* {@link .HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader} with an OkHttp based

* {@link com.bumptech.glide.load.model.ModelLoader}.

*

*

* If you're using gradle, you can include this module simply by depending on the aar, the module will be merged

in by manifest merger. For other build systems or for more more information, see

* {@link GlideModule}.

*

*/

public class OkHttpGlideModule implements GlideModule {

@Override

public void applyOptions(Context context, GlideBuilder builder) {

// Do nothing.

}

;@Override

public void registerComponents(Context context, Glide glide) {

//注意:new HTTPSUtils(context).getInstance()为已经通过认证的okhttpclient

glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(new HTTPSUtils(context).getInstance()));

}

}

稍后具体讲解registerComponents里面的实现方法

2.2 删除build.gradle里面的依赖

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

2.3 在Manifest.xml配置拷贝过来的OkHttpGlideModule。

android:name="com.example.appuser.testother.utils.https.OkHttpGlideModule "

android:value="GlideModule"/>

走完三步即可,glide加载图片的方式还是照旧。

接着我们好好说说如何对glide进行配置让他能展示

方案一:信任所有证书

/**

* 信任所有https证书

*/

private SSLContext overlockCard()

{

final TrustManager[] trustAllCerts = new TrustManager[]{new 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() {

X509Certificate[] x509Certificates = new X509Certificate[0];

return x509Certificates;

}

}};

try

{

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

sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

return sslContext;

}

catch (Exception e){

return null;

}

}

@Override

public void registerComponents(Context context, Glide glide)

{

OkHttpClient.Builder clientBuilder=new OkHttpClient.Builder();

OkHttpClient.Builder builder = new OkHttpClient.Builder()

.sslSocketFactory(overlockCard().getSocketFactory())

.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session)

{

//忽略域名检验

return true;

}

});

glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(clientBuilder.build()));

}

方案二:信任服务器的证书

@Override

public void registerComponents(Context context, Glide glide)

{

OkHttpClient.Builder clientBuilder=new OkHttpClient.Builder();

InputStream certificate=getAsserts.open("zs.cer");

try {

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

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

keyStore.load(null);

int index = 0;

keyStore.setCertificateEntry("1", certificateFactory.generateCertificate(certificate));

try {

if (certificate != null)

certificate.close();

} catch (IOException e) {

}

}

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

TrustManagerFactory trustManagerFactory =

TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

trustManagerFactory.init(keyStore);

sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

X509TrustManager trustManager = Platform.get().trustManager(sslSocketFactory);

clientBuilder.sslSocketFactory(sslSocketFactory, trustManager);

clientBuilder.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

return true;

}

});

glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(clientBuilder.build()));

}

这一篇到此为止,希望各位多多点评,下一篇会详细写一下在使用https 自签证书时如何双向验证。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。