最近公司项目需要,网络协议支持https,之前接触不多,所以这次想总结一下https在android开发中的相关内容
一、https证书
对于https和证书的概念,大家可以自行搜索百度。
证书分两种:
1、花钱向认证机构购买的证书,(我们公司买的证书一个就需要4000元,TMD,还不如多租一台服务器)。服务器如果使用了此类证书的话,那对于移动端来说,直接可以忽略此证书,直接用https访问。与之不同的是ios内置了很多信任的证书,所以他们不需要做任何操作
2、另一种是自己制作的证书,使用此类证书的话是不受信任的,也不需要花钱,所以需要我们在代码中将此类证书设置为信任证书
二、如何忽略证书
1、服务器的哥们如果加上了证书的话,那么你们的网络请求的url将从http:xx改成https:xx,如果你直接也将http改成https的话而什么也不做的话,客户端将直接报错,如图:
意思就是没有找到本地证书,那就开始构建一个SSL来信任所有的证书,忽略证书其实就是如此。
2、新建一个类
public class SSLSocketClient { //获取这个SSLSocketFactory public static SSLSocketFactory getSSLSocketFactory() { try { SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, getTrustManager(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } } //获取TrustManager private static TrustManager[] getTrustManager() { TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; return trustAllCerts; } }
通过这个类我们可以获得SSLSocketFactory,这个东西就是用来管理证书和信任证书的
但是有一点需要注意:
然后我们在okhttp中设置SSLSocketFactory,如图:
运行之后,发现还是会报错,如图:
意思是我们的请求证书和服务器的证书不一致,这是因为我们还需要配置一个HostnameVerifier来忽略host验证
三、在SSLSocketClient的类中再加入一个方法:
//获取HostnameVerifier public static HostnameVerifier getHostnameVerifier() { HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }; return hostnameVerifier; }
然后再okhttp中配置一下HostnameVerifier:
在运行,可以正常访问了
四、整体配置
copy整个工具类到你的项目中:
/** * Created by Anonymous on 2017/6/13. */ public class SSLSocketClient { //获取这个SSLSocketFactory public static SSLSocketFactory getSSLSocketFactory() { try { SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, getTrustManager(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } } //获取TrustManager private static TrustManager[] getTrustManager() { TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; return trustAllCerts; } //获取HostnameVerifier public static HostnameVerifier getHostnameVerifier() { HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }; return hostnameVerifier; } }
然后再okhttp中配置
mHttpClient = new OkHttpClient().newBuilder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) .addInterceptor(new LogInterceptor()) .addInterceptor(new TokenInterceptor()) .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())//配置 .hostnameVerifier(SSLSocketClient.getHostnameVerifier())//配置 .build();
如果你用的是retrofit,在retrofit中配置一下okhttp即可
retrofitAPI = new Retrofit.Builder() .baseUrl(AppConfig.baseUrl) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(mHttpClient)//配置okhttp .build() .create(RetrofitAPI.class);
这样你就可以忽略https证书正常访问你的网络了,本人android小白,说的不对了,希望大神能指出,也希望大家多多支持小牛知识库。
问题内容: 我想在通过内部公司链接向服务器发出请求时忽略。 使用python库,我可以这样做: 如何使用urllib2库做同样的事情? 问题答案: 同时,urllib2似乎默认情况下会验证服务器证书。过去显示 的警告在2.7.9中消失了,我目前在具有自签名证书(和Python 2.7.9)的测试环境中遇到此问题。 我evil的解决方法(在生产中不要这样做!): 根据文档,直接调用SSLContex
我正在对具有自签名证书的私有服务使用urllib3。有什么方法可以让urllib3忽略证书错误并提出请求吗? 在使用以下各项时: 出现以下错误: 使用我能够从服务中获得预期的响应
主要内容:自签名证书错误,Maven依赖关系,接受自签名证书通常,开发人员将在本地机器上或项目的开发阶段使用自签名证书。 默认情况下,HttpClient(和Web浏览器)不会接受不可信的连接。 但是,可以配置以允许不可信的自签名证书。 注意:这是一个可能存在安全风险,因为您将其用于生产时,基本上会禁用所有的认证检查,这可通导致受到攻击。 在这个例子中,我们演示了如何忽略Apache HttpClient 4.5中的SSL / TLS证书错误。 自签名证书
问题内容: 我将urllib3用于具有自签名证书的私有服务。有什么办法可以让urllib3忽略证书错误并仍然发出请求? 使用以下内容时: 引发以下错误: 使用我能够从服务中获得预期的响应 问题答案: 尝试以下代码: 请参阅将assert_hostname设置为False将禁用SSL主机名验证
问题内容: URL myUrl = new URL(“https://www....."); 网站的SSL证书已过期。如何避免它并使URL()工作? 问题答案: 您应该构建一个包装默认信任管理器的,捕获并忽略它。 注意:如此答案中所述,此设置是否安全在很大程度上取决于实现。特别是,它依赖于在正确检查所有其他内容之后最后执行的日期验证。 遵循这些原则的东西应该起作用: 当证书有问题时,信任管理器将抛
问题内容: Apache Http客户端。您可以在此处查看相关代码: 这是每个人都用来忽略SSL证书错误的方法(仅将其设置为登台,它将不会在生产中使用)。但是,我仍然收到以下异常/堆栈跟踪: 任何提示都很好。如果我做的TrustManager错误,或者我应该以不同的方式执行HTTP Post方法,则可以选择两种方式。 谢谢! 问题答案: 首先,不要 忽略 证书错误。与他们打交道。忽略证书错误将打开