博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【漏洞修复】自定义实现的X509TrustManager子类中..
阅读量:4030 次
发布时间:2019-05-24

本文共 4908 字,大约阅读时间需要 16 分钟。

漏洞说明

/**     * 覆盖java默认的证书验证     */    private static final TrustManager[] TRUSTALLCERTS = new TrustManager[]{            new X509TrustManager() {                public java.security.cert.X509Certificate[] getAcceptedIssuers() {                    return new java.security.cert.X509Certificate[]{};                }                @SuppressLint("TrustAllX509TrustManager")                public void checkClientTrusted(X509Certificate[] chain, String authType) {                }                @SuppressLint("TrustAllX509TrustManager")                public void checkServerTrusted(X509Certificate[] chain, String authType) {                }            }    }; try {            SSLContext sc = SSLContext.getInstance("TLS");            sc.init(null, TRUSTALLCERTS, new java.security.SecureRandom()); //配置自己的信任管理类(信任策略)            SSLSocketFactory newFactory = sc.getSocketFactory();            connection.setSSLSocketFactory(newFactory);        } catch (Exception e) {            e.printStackTrace();        }

如上代码所示,自定义与使用了X509TrustManager子类,但又没有实现信任校验的逻辑时遇,对安全平台扫描APK时,会报如下风险

【漏洞】自定义实现的X509TrustManager子类中,未对服务器端证书做验证,默认接受任意服务端证书,会存在安全风险,可能会导致恶意程序利用中间人攻击绕过证书校验

【修复的建议通常的如下】

利用X509TrustManager子类中的checkServerTrusted函数,校验服务器端证书的合法性

PS:一般自定义信任管理器,通常是使用自签名或android不认可的证书颁发机构SSL证书的业务场景

使用这个方式最麻烦是公钥/证书放置在前端,以及公钥的同步等问题!!!

修复建议

个人的修复建议是

【前提条件】
1、你的SSL证书是由android认可的证书颁发机构或者该结构下属的机构颁发的证书(最关键)
2、使用的https的服务的请求与响应的数据安全性不是那么高(数据不敏感与私密),
3、又不保证服务器的证书是否不会被替换,
那么性价较高且简单明了的方案是

不要使用509TrustManager子类!

不要使用509TrustManager子类!
不要使用509TrustManager子类!
即使用默认的系统网络库默认的信任管理/校验方案,系统会使用证书链的信任管理策略

PS:

Android已经把将近150个CA根证书(数字证书认证机构认证过的证书)内置在我们手机中。这150多个证书被全世界信赖

TIPS分享

查看域名的证书的信息

利用chrome打开对应的域名,查看即可

在这里插入图片描述
证书详情
在这里插入图片描述

查看信息的信证CA根证书

设置->安全->信任的凭据

在这里插入图片描述

自定义X509TrustManage示例

说明 : 如下代码copy自

public static SSLSocketFactory getSSLSocketFactory() throws Exception {                final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {            // 本地公钥信息,实现项目中在考虑该值的更新,否则服务证书一换,之前的端不会能正常工作了            public static final String PUB_KEY = "3082010a0282010100d52ff5dd432b3a05113ec1a7065fa5a80308810e4e181cf14f7598c8d553cccb7d5111fdcdb55f6ee84fc92cd594adc1245a9c4cd41cbe407a919c5b4d4a37a012f8834df8cfe947c490464602fc05c18960374198336ba1c2e56d2e984bdfb8683610520e417a1a9a5053a10457355cf45878612f04bb134e3d670cf96c6e598fd0c693308fe3d084a0a91692bbd9722f05852f507d910b782db4ab13a92a7df814ee4304dccdad1b766bb671b6f8de578b7f27e76a2000d8d9e6b429d4fef8ffaa4e8037e167a2ce48752f1435f08923ed7e2dafef52ff30fef9ab66fdb556a82b257443ba30a93fda7a0af20418aa0b45403a2f829ea6e4b8ddbb9987f1bf0203010001";            @Override            public void checkClientTrusted(                    java.security.cert.X509Certificate[] chain,                    String authType) throws CertificateException {            }                        @Override            public void checkServerTrusted(                    java.security.cert.X509Certificate[] chain,                    String authType) throws CertificateException {                if (chain == null) {                    throw new IllegalArgumentException("checkServerTrusted:x509Certificate array isnull");                }                if (!(chain.length > 0)) {                    throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");                }                if (!(null != authType && authType.equalsIgnoreCase("RSA"))) {                    throw new CertificateException("checkServerTrusted: AuthType is not RSA");                }                                try {                    TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");                    tmf.init((KeyStore) null);                    for (TrustManager trustManager : tmf.getTrustManagers()) {                        ((X509TrustManager) trustManager).checkServerTrusted(chain, authType);                    }                } catch (Exception e) {                    throw new CertificateException(e);                }                                                RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();                String encoded = new BigInteger(1 , pubkey.getEncoded()).toString(16);                                final boolean expected = PUB_KEY.equalsIgnoreCase(encoded);                if (!expected) {                    throw new CertificateException("checkServerTrusted: Expected public key: "                            + PUB_KEY + ", got public key:" + encoded);                }            }            @Override            public java.security.cert.X509Certificate[] getAcceptedIssuers() {                return new java.security.cert.X509Certificate[0];            }        }};                final SSLContext sslContext = SSLContext.getInstance("TLS");        sslContext.init(null, trustAllCerts,                new java.security.SecureRandom());                return sslContext                .getSocketFactory();    }

相关文档

转载地址:http://lkmbi.baihongyu.com/

你可能感兴趣的文章
No.175 - LeetCode1306
查看>>
No.176 - LeetCode1309
查看>>
FE:http状态码
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
mac:移动python包路径
查看>>
mysql:sql create database新建utf8mb4 数据库
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql alter table 修改列属性的字符集
查看>>
mysql:sql drop table (删除表)
查看>>
mysql:sql truncate (清除表数据)
查看>>
scrapy:xpath string(.)非常注意问题
查看>>
yuv to rgb 转换失败呀。天呀。谁来帮帮我呀。
查看>>
yuv420 format
查看>>
单纯的把Y通道提取出来能正确显示出灰度图来为什么我的Qt就显示不出来呢转换有问题呀?
查看>>
YUV420只绘制Y通道
查看>>
yuv420 还原为RGB图像
查看>>
LED恒流驱动芯片
查看>>
驱动TFT要SDRAM做为显示缓存
查看>>
使用file查看可执行文件的平台性,x86 or arm ?
查看>>
qt5 everywhere 编译summary
查看>>