Android中的“javax.net.ssl.SSLException:不受信任的服务器证书”异常

时间:2010-06-16 16:16:18

标签: java android

当我尝试从Android应用中点击HTTPS URL(.Net Webservice)时,我收到此异常:

  

javax.net.ssl.SSLException:不受信任的服务器证书

这是我的代码:

HttpParams myParams = new BasicHttpParams();
HttpProtocolParams.setVersion(myParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(myParams, "utf-8");
myParams.setBooleanParameter("http.protocol.expect-continue", false);


HttpConnectionParams.setConnectionTimeout(myParams, 100000); 
HttpConnectionParams.setSoTimeout(myParams, 100000);

//
KeyStore trusted;
try {  

        trusted = KeyStore.getInstance("pkcs12");
        trusted.load(null, "".toCharArray());
        SSLSocketFactory sslf = new SSLSocketFactory(trusted);
  sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

  SchemeRegistry schemeRegistry = new SchemeRegistry(); 
  schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

  schemeRegistry.register(new Scheme("https", sslf, 443));    
  ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(myParams, schemeRegistry);


  httpClient = new DefaultHttpClient(manager, myParams); 
  } catch (KeyStoreException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchAlgorithmException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (CertificateException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (KeyManagementException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnrecoverableKeyException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }         
    //

    localContext = new BasicHttpContext();  

    httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); 

    httpPost = new HttpPost("https://...."); 
    response = null; 

    StringEntity tmp = null;         

    httpPost.setHeader("SOAPAction", "SoapActionURL"); 

    if (contentType != null) { 
        httpPost.setHeader("Content-Type", contentType); 
    } else { 
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
    } 

    try { 
        tmp = new StringEntity(data,"UTF-8"); 
    } catch (UnsupportedEncodingException e) { 
        Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e); 
    } 

    httpPost.setEntity(tmp); 

    try { 

        response = httpClient.execute(httpPost,localContext); 

        if (response != null) { 
            ret = EntityUtils.toString(response.getEntity()); 
        } 
    } catch (Exception e) { 
        Log.e("Your App Name Here", "HttpUtils: " + e); 
    }  

1 个答案:

答案 0 :(得分:1)

KeyStore trusted;
try {  

        trusted = KeyStore.getInstance("pkcs12");
        trusted.load(null, "".toCharArray());
        SSLSocketFactory sslf = new SSLSocketFactory(trusted);

您没有信任库存储您要连接的服务器的证书,并且您要连接的服务器不受信任。要解决此问题,您需要使用Keytool(我创建了一个BKS密钥库并使用SpongyCastle提供程序加载它)作为信任库来创建密钥库文件。

keytool -importcert -file servercert.crt -alias mykey -keystore truststore.jks -storetype BKS -providerpath bcprov-jdk15on-151.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider

另外,我使用了更新版本的Apache HttpClient,特别是http://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient-android/4.3.5

public KeyStore initializeTrustStore(Context context)
{
    KeyStore keyStore = null;
    try
    {
        keyStore = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME);
        InputStream inputStream = context.getResources().openRawResource(R.raw.truststore);
        try
        {
            keyStore.load(inputStream, "password".toCharArray());
        }
        finally
        {
            inputStream.close();
        }
    }


    KeyStore trustStore = loadTrustStore(context);
    SSLContext sslcontext = null;
    CloseableHttpClient httpclient = null;

        SSLContextBuilder sslContextBuilder = SSLContexts.custom()
            .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
        sslcontext = sslContextBuilder.build();

        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext, new String[] {"TLSv1"}, null,
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
        );
        httpclient = HttpClients
            .custom()
            .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
            .setSSLSocketFactory(sslsf).build();
        CloseableHttpResponse response = httpclient.execute(httpUriRequest);
        try
        {
            HttpEntity entity = response.getEntity();
            //do things with response here
            if(entity != null)
            {
                entity.consumeContent();
            }
        }
        finally
        {
            response.close();
        }