Android 使用自签名证书

Android SSL可以使用CA证书也可以使用自签名证书,自签名证书是通过keystore生成的,本文介绍android端使用自签名证书过程。
1,拷贝自签名证书到assert目录下,方便读取。
2,修改网络请求工具类OkHttpClientManager,如下所示:

public void setCertificates(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)
            {
            }
        }

        SSLContext sslContext = SSLContext.getInstance("TLS");

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

        trustManagerFactory.init(keyStore);
        sslContext.init
            (   
                null, 
                trustManagerFactory.getTrustManagers(), 
                new SecureRandom()
            );
       mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());


    } catch (Exception e)
    {
        e.printStackTrace();
    } 

}

3,在application中使用,

public class MyApplication extends Application
{
   @Override
    public void onCreate()
    {
        super.onCreate();

        try
        {
            OkHttpClientManager.getInstance()
                    .setCertificates(getAssets().open("srca.cer"));
        } catch (IOException e)
        {
            e.printStackTrace();
        }


}

以上是单向验证,只要客户端获取了包含服务端公钥的证书即可。

下面介绍双向验证,单向验证是服务端有"kjs文件",客户端有" cer文件",那么双向验证就是客户端也有一个"kjs文件",服务端也有一个"cer文件",实现步骤如下:
1,修改网络请求工具类:

public void setCertificates(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)
            {
            }
        }

        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.
                getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);

        //初始化keystore
        KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        clientKeyStore.load(mContext.getAssets().open("zhy_client.jks"), "123456".toCharArray());

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(clientKeyStore, "123456".toCharArray());

        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());


    } catch (Exception e)
    {
        e.printStackTrace();
    } 

}

2,将"jks文件"改为"bks文件",因为Java平台默认识别jks格式的证书文件,但是android平台只识别bks格式的证书文件。下载Download portecle-1.9.zip (3.4 MB)。
解压后,里面包含bcprov.jar文件,使用jave -jar bcprov.jar即可打开GUI界面。
然后修改代码为:

//初始化keystore
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(mContext.getAssets().open("zhy_client.bks"), "123456".toCharArray());

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, "123456".toCharArray());

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

参考文章:
http://blog.csdn.net/lmj623565791/article/details/48129405

你可能感兴趣的:(Android 使用自签名证书)