Https证书验证相关;security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Https 中用到的证书术语,大概关系

CA机构:颁发证书的机构,你的域名想上Https,需要在CA机构注册,申请证书,如百度https://www.baidu.com/的证书
服务器证书:如https://www.baidu.com/,对应一家公司,去CA申请证书后,会有一个证书(服务器程序会用到),下文中将此类证书称为服务器证书
根证书:CA机构用来加解密,验证你申请证书的证书,每个平台会内置这些CA机构的证书(也叫根证书)如 Android,程序与https通信的时候会用到根证书验证Https URL对应的证书是否合法

查看一个域名的服务器证书和CA根证书

如:https://www.baidu.com/域名
在谷歌浏览器中打开https://www.baidu.com/可以看到(如下图),点击安全图标出现如下弹框
在这里插入图片描述
点击证书可以查看证书相关内容:颁发者,有效期等
在这里插入图片描述
导出服务器证书 : 点击详细信息->复制到文件->下一步->选择格式DER ->下一步,直到导出成功 最后会有一个**.cer**的证书文件
导出CA根证书 :点击根证书路径->点击最上面的根证书->剩下步骤就和导出服务器证书一样
在这里插入图片描述

window上证书查看

window+R 下输入certmgr.msc,确定
在这里插入图片描述
出现证书列表:选择某个证书,双击出现证书界面,导出就和上面的操作一样
在这里插入图片描述

查看Android 设备上的证书,安装证书到Android设备

查看设备上的证书

adb shell
cd system/etc/security/cacerts/
#列出所有证书,如下图 ,一堆57692373.0文件
ls 
#查找某个机构颁发的证书 如 cfca
grep -inr "cfca" ./
#查看某个证书文件
cat 9282e51c.0

列出所有证书
在这里插入图片描述
查找某个机构颁发的证书 如 cfca,查看cfca证书文件
在这里插入图片描述
安装证书

  1. 把之前的.cer根证书文件push到android设备上
adb push "C:\Users\my\Desktop\CFCA EV ROOT.cer" /sdcard/baidu
  1. 在设置中安装证书
    进入设置->安全->从手机存储安装(从手机存储安装证书),不同设备可能位置不一样;选择刚才push的证书文件
    在这里插入图片描述
    note:如果是ODM公司,rom开发可以把根证书内置到系统中

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

上面的错误是在一个Android 5.0的设备的Https请求中的,其他设备没问题;通过上面的步骤安装完证书就好了,然而这种方法只能验证问题,不能当做解决问题的方案。下面提供两个解决思路

  1. 服务器提供的https接口,注册的CA机构根证书不是很通用,在某些设备上没有,那就需要服务器更换证书,换一个更通用的CA机构,思路没毛病,服务器的问题。
  2. 终端处理:
  • 忽略https根证书验证,设置信任所有服务器证书(有点违背使用https的原则,不安全)
  • 终端内置服务器证书,修改证书验证逻辑,与内置的服务器证书匹配(证书公钥,颁发机构,颁发给谁等信息)就算验证通过
  • 终端内置根证书,代码安装根证书

OkHttp的https证书验证逻辑
使用OkHttp默认证书验证逻辑:不设置sslSocketFactory和hostnameVerifier,默认使用系统的根证书验证服务器证书,如果对应的根证书不存在,报错Trust anchor for certification path not found.;这种就适合使用CA的证书(也有可能CA机构的根证书不够通用而没有内置),不适合像12306这种自己颁发的证书
自定义自己的证书验证逻辑:直接让所有的服务器证书通过不验证;比较服务器证书公钥,颁发机构,颁发给谁等信息验证某个特定的服务器证书

相关代码
OkHttp默认证书验证逻辑
在这里插入图片描述

  private X509TrustManager systemDefaultTrustManager() {
   
    try {
   
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
          TrustManagerFactory.getDefaultAlgorithm());
      trustManagerFactory.init((KeyStore) null);
      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];
    } catch (GeneralSecurityException e) {
   
      throw assertionError("No System TLS", e); // The system has no TLS. Just give up.
    }
  }

  private SSLSocketFactory systemDefaultSslSocketFactory(X509TrustManager trustManager) {
   
    try {
   
      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, new TrustManager[] {
    trustManager }, null);
      return sslContext.getSocketFactory();
    } catch (GeneralSecurityException e) {
   
      throw assertionError("No System TLS", e); // The system has no TLS. Just give up.</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值