二、自签名证书

什么是自签名证书(self-signed certicates)?

自签名证书就是没有通过受信任的证书颁发机构, 自己给自己颁发的证书.

SSL 证书大致分三类:

  • 由安卓认可的证书颁发机构CA(Certificate Authority)(如: VeriSign、DigiCert), 或这些机构的下属机构颁发的证书.
  • 没有得到安卓认可的证书颁发机构颁发的证书.
  • 自己颁发的证书, 分临时性的(在开发阶段使用)或在发布的产品中永久性使用的两种.

而只有Android系统认可的机构办法的证书,在使用过程中才不会出现安全提示。

为什么会有人使用自签名的证书呢?

(重要的事重复三遍)免费,免费,免费,不用花费一分钱,在开发阶段写的代码, 测试跟发布的时候也可以用。

三、OkHttp3添加自签名证书

  1. 如何使用自签名证书?

1.获取证书流有两种方式:

  • 将服务端提供的证书文件放到assets文件夹里面,然后获取。(因为是在assets文件下,所以会写入到apk里面)
  • 打开证书文件,将证书里面的内容以字符串的形式通过流写入。(不会写入到apk中)

2.创建秘钥,添加证书进去

3.创建信任管理器,并把秘钥初始化到信任管理器里

4.获取SLL上下文,并把信任管理器初始化到SSL里

5.获取socket工厂,设置到okhttpclient中

6.检验主机名

if (UrlConsts.serverUrl.contains(“https://”)){

InputStream cerInputStream = null;

try {

//方式一:在assets中获取证书

cerInputStream = context.getAssets().open(“ssl.cer”);

//方式二:把字符串通过流的形式获取证书

// cerInputStream = new ByteArrayInputStream(cerText.getBytes(“UTF-8”));

//获取socket工厂

SSLSocketFactory sslSocketFactory = SSLUtil.getSSLSocketFactory(cerInputStream);

//okhttp设置socket工厂

okHttpClientBuilder.sslSocketFactory(sslSocketFactory);

} catch (IOException e) {

e.printStackTrace();

}

}

//检验主机名

okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

return true;

}

});

public class SSLUtil {

/**

  • 返回SSLSocketFactory

  • @param certificates 证书的输入流

  • @return SSLSocketFactory

*/

public static SSLSocketFactory getSSLSocketFactory(InputStream… certificates) {

return getSSLSocketFactory(null,certificates);

}

/**

  • 双向认证

  • @param keyManagers KeyManager[]

  • @param certificates 证书的输入流

  • @return SSLSocketFactory

*/

public static SSLSocketFactory getSSLSocketFactory(KeyManager[] keyManagers, InputStream… certificates) {

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

e.printStackTrace();

}

}

//创建信任管理工厂

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

//初始化信任管理器

trustManagerFactory.init(keyStore);

//获取SSL上下文对象

SSLContext sslContext = SSLContext.getInstance(“TLS”);

//初始化信任管理器

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

//获取socket工厂

SSLSocketFactory socketFactory = sslContext.getSocketFactory();

return socketFactory;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

测试运行,完美解决。

2.信任所有证书(不建议使用)

服务端提供的证书文件,如果服务端更改了需要客户端进行相应的更改,否则无法请求服务端数据。如果想不换证书可以继续访问,可以通过X509TrustManager信任所有的证书,以达到客户端不换证书文件就能获取到服务端数据,但不建议这样使用!!!

/**

*信任所有证书(不建议使用)

  • @return

*/

public static SSLSocketFactory getAllSSLSocketFactory(){

//创建X509信任管理器

TrustManager[] trustManagers = new TrustManager[]{

new X509TrustManager() {

@Override

public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

}

@Override

public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

}

@Override

public X509Certificate[] getAcceptedIssuers() {

return new X509Certificate[0];

}

}

};

try {

//获取SSL上下文对象

SSLContext sslContext = SSLContext.getInstance(“TLS”);

//初始化无信任管理器

sslContext.init(null, trustManagers, new SecureRandom());

//获取socket工厂

SSLSocketFactory socketFactory = sslContext.getSocketFactory();

return socketFactory;

} catch (NoSuchAlgorithmException | KeyManagementException e) {

e.printStackTrace();

}

return null;

}

四、Glide4.0以上 添加自签名证书

Glide 直接加载没有权威机构颁发的证书https的URL会直接抛出错误SSLHandshakeException(CertPathValidatorException证书路径验证器异常)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

在这里插入图片描述

看到CertPathValidatorException这个异常,不用多说也知道什么原因导致的,所以我们需要对Glide内部的Okhttp3进行https自签名。

最后

都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。

技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;

我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

Android架构视频+BAT面试专题PDF+学习笔记​》

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。

…(img-GmVeY4Of-1644988509706)]

[外链图片转存中…(img-Olbp0Je2-1644988509707)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。

Logo

一站式 AI 云服务平台

更多推荐