Android使用https单向认证的坑

关于android使用https单向认证遇到的坑

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

场景:离线环境中使用服务器端自建的SSL证书,android端使用retrofit实现https请求,实现单向认证。

在网上参考了很多博客,还是没能解决,终于在这一篇博客Https系列之一:https的简单介绍及SSL证书的生成发现了是证书的问题。

服务器的证书是使用JDK自带的Keytool工具生成,制作证书的时候没有写上服务器的IP地址,所以会出现这个错误。

关于如何使用Retrofit实现https单向认证,参考如下:

Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

retrofit遇上https自签名证书

最后的最后,对SSLSocketFactoryUtils做了一些小更改:

public class SSLSocketFactoryUtils {
    static int keyServerStroreID = R.raw.tomcat_server;

    public static SSLSocketFactory createSSLSocketFactory(Context context) {
        InputStream trustStream = context.getResources().openRawResource(keyServerStroreID);
        SSLSocketFactory mSSLSocketFactory = null;
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{getTurstManager(trustStream)}, new SecureRandom());
            mSSLSocketFactory = sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return mSSLSocketFactory;
    }

    /**
     * 获得指定流中的服务器端证书库
     */
    public static X509TrustManager getTurstManager(InputStream certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            Certificate certificate = certificateFactory.generateCertificate(certificates);
            keyStore.setCertificateEntry("ca",certificate);
            if (certificates!=null){
                certificates.close();
            }
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.
                    getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            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 (Exception e) {
            Log.e("httpDebug", "SSLSocketFactoryUtils", e);
        }
        return null;
    }

    public static void  SSLSocketFactoryUtils(Context context) {
        try {
            InputStream inStream = context.getResources().openRawResource(keyServerStroreID);
            // 创建X509工厂类
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            // 创建证书对象
            X509Certificate oCert = (X509Certificate) cf.generateCertificate(inStream);
            inStream.close();
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
            String info = null;
            // 获得证书版本
            info = String.valueOf(oCert.getVersion());
            Log.e("TAG", "证书版本:" + info);
            // 获得证书序列号
            info = oCert.getSerialNumber().toString(16);
            Log.e("TAG", "证书序列号:" + info);
            // 获得证书有效期
            Date beforedate = oCert.getNotBefore();
            info = dateformat.format(beforedate);
            Log.e("TAG", "证书生效日期:" + info);
            Date afterdate = oCert.getNotAfter();
            info = dateformat.format(afterdate);
            Log.e("TAG", "证书失效日期:" + info);
            // 获得证书主体信息
            info = oCert.getSubjectDN().getName();
            Log.e("TAG", "证书拥有者:" + info);
            // 获得证书颁发者信息
            info = oCert.getIssuerDN().getName();
            Log.e("TAG", "证书颁发者:" + info);
            // 获得证书签名算法名称
            info = oCert.getSigAlgName();
            Log.e("TAG", "证书签名算法:" + info);
        } catch (CertificateException e) {
            e.printStackTrace();
            Log.e("TAG", "出错");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("TAG", "出错");
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值