android L中使用bouncy castle的Https身份验证

android L中使用bouncy castle的Https身份验证,https,android-5.0-lollipop,bouncycastle,urlconnection,Https,Android 5.0 Lollipop,Bouncycastle,Urlconnection,因此,自从apache库在Android L中被弃用以来,我一直在尝试使用UrlConnection api在web sphere服务器上实现ssl身份验证。代码如下: 调用web服务的函数 SSLContext ctx = SSLContext.getInstance("TLS"); try { ctx.init(null, new TrustManager[] { new UDMX509TrustManager( Con

因此,自从apache库在Android L中被弃用以来,我一直在尝试使用UrlConnection api在web sphere服务器上实现ssl身份验证。代码如下:

调用web服务的函数

SSLContext ctx = SSLContext.getInstance("TLS");
        try
        {
        ctx.init(null, new TrustManager[] { new UDMX509TrustManager(
            Constants.UDM_SERVER_SOURCE) }, new SecureRandom());
        } catch (Exception e)
        {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }    
URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection) url
            .openConnection();
        urlConnection.setReadTimeout(10000 /* milliseconds */);
        urlConnection.setConnectTimeout(15000 /*
                           * milliseconds
                           */);
        urlConnection.setSSLSocketFactory(ctx.getSocketFactory());
        if (jsonObject != null)
        {
        urlConnection.setRequestMethod("POST");
        urlConnection.setRequestProperty("Content-Type",
            "application/json");
        DataOutputStream printout = new DataOutputStream(
            urlConnection.getOutputStream());
        printout.writeBytes(URLEncoder.encode(jsonObject.toString(),
            "UTF-8"));
        printout.flush();
        printout.close();
        InputStream in = urlConnection.getInputStream();
        Reader reader = null;
        reader = new InputStreamReader(in, "UTF-8");
        char[] buffer = new char[1000];
        reader.read(buffer);
        response = new String(buffer);
        MLog.v("response is", response);
        }/*
          * catch (Exception e) { e.printStackTrace(); } }
          */else
        {
        return response = Constants.NETWORK_UNAVAILABLE;
        }
        /*
         * } catch (Exception e) { e.printStackTrace(); }
         */
我的定制X509管理器是:

public class UDMX509TrustManager implements X509TrustManager
{
    /*
     * The default X509TrustManager returned by IbmX509. We'll delegate
     * decisions to it, and fall back to the logic in this class if the default
     * X509TrustManager doesn't trust it.
     */
    X509TrustManager pkixTrustManager;

    public UDMX509TrustManager(int source) throws Exception
    {
    // create a "default" JSSE X509TrustManager.
    KeyStore ks = KeyStore.getInstance("BKS");
    InputStream in = null;
    int resId = 0;
    if (source == Constants.UDM_SERVER_SOURCE)
    {
        resId = Constants.SERVER_KEYSTORE_PATH;
    } else if (source == Constants.MQTT_SERVER_SOURCE)
    {
        resId = Constants.MQTT_KEYSTORE_PATH;
    }
    in = VerizonUdmApplication.getContext().getResources()
        .openRawResource(resId);
    ks.load(in, Constants.KEYSTORE_PASSWORD.toCharArray());
    in.close();
    TrustManagerFactory tmf = TrustManagerFactory
        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);

    TrustManager tms[] = tmf.getTrustManagers();

    /*
     * Iterate over the returned trustmanagers, look for an instance of
     * X509TrustManager. If found, use that as our "default" trust manager.
     */
    for (int i = 0; i < tms.length; i++)
    {
        if (tms[i] instanceof X509TrustManager)
        {
        pkixTrustManager = (X509TrustManager) tms[i];
        return;
        }
    }

    /*
     * Find some other way to initialize, or else we have to fail the
     * constructor.
     */
    throw new Exception("Couldn't initialize");
    }

    /*
     * Delegate to the default trust manager.
     */
    public void checkClientTrusted(X509Certificate[] chain, String authType)
        throws CertificateException
    {
    try
    {
        pkixTrustManager.checkClientTrusted(chain, authType);
    } catch (CertificateException excep)
    {
        // do any special handling here, or rethrow exception.
    }
    }

    /*
     * Delegate to the default trust manager.
     */
    public void checkServerTrusted(X509Certificate[] chain, String authType)
        throws CertificateException
    {
    try
    {
        pkixTrustManager.checkServerTrusted(chain, authType);
    } catch (CertificateException excep)
    {
        /*
         * Possibly pop up a dialog box asking whether to trust the cert
         * chain.
         */
    }
    }

    /*
     * Merely pass this through.
     */
    public X509Certificate[] getAcceptedIssuers()
    {
    return pkixTrustManager.getAcceptedIssuers();
    }
}
公共类UDMX509TrustManager实现X509TrustManager
{
/*
*IbmX509返回的默认X509TrustManager。我们将委派
*如果默认设置为
*X509TrustManager不信任它。
*/
X509TrustManager pkixTrustManager;
公共UDMX509TrustManager(int源代码)引发异常
{
//创建一个“默认”JSSE X509TrustManager。
KeyStore ks=KeyStore.getInstance(“BKS”);
InputStream in=null;
int剩余=0;
if(source==Constants.UDM\u SERVER\u source)
{
resId=Constants.SERVER_密钥库_路径;
}else if(source==Constants.MQTT_SERVER_source)
{
resId=Constants.MQTT_密钥库_路径;
}
in=VerizonudMapApplication.getContext().getResources()
.openRawResource(REDIS);
load(in,Constants.KEYSTORE_PASSWORD.toCharArray());
in.close();
TrustManagerFactory tmf=TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
TrustManager tms[]=tmf.getTrustManager();
/*
*迭代返回的TrustManager,查找
*X509TrustManager。如果找到,将其用作我们的“默认”信任管理器。
*/
对于(int i=0;i
目前为止,我已经创建了两个场景:

  • 使用机器ip作为公共名称参数生成bks:- 在这种情况下,我得到的异常是:java.io.ioexception:hostname 未验证“xx.xx.xx.xx”

  • 以域名作为公共名称参数生成bks:- 我在本例中遇到的例外情况是:
    java.net.UnknownHostException:无法解析主机“主机名”:否 与主机名关联的地址

另请注意-出于测试目的,我使用的是tomcat服务器。我知道如何解决这个问题并使用此api完成服务器的身份验证吗? 在此方面的任何帮助都将不胜感激