2015-06-08 1 views
0

Я пытаюсь отправить HTTP-запрос на сервер приложений, защищенный с помощью SSL. У меня есть самоподписанный сертификат X.509 от команды сервера. Я последовал за учебник от documentation, но все-таки получил SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.Не удается реализовать SSL-соединение с сервером с использованием самозаверяющего сертификата

Я использую этот код:

CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); 

AssetManager assManager = ShoppingHelperApp.getContext().getAssets(); 
InputStream is = assManager.open("keystore2.crt"); 
InputStream caInput = new BufferedInputStream(is); 
Certificate ca = cf.generateCertificate(caInput); 
caInput.close(); 

String keyStoreType = KeyStore.getDefaultType(); 
KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
keyStore.load(null, null); 
keyStore.setCertificateEntry("ca", ca); 

String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
tmf.init(keyStore); 

context = SSLContext.getInstance("TLS"); 
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
conn.setSSLSocketFactory(context.getSocketFactory()); 

Кто-нибудь имеет понятия, как решить эту проблему?

ответ

0

Это, как я сделал нечто подобное создать OkHttpClient:

OkHttpClient client = new OkHttpClient(); 
     try { 
      KeyStore keyStore = SSLUtils.getKeyStore(applicationContext); 
      SSLContext sslContext = SSLContext.getInstance("SSL"); 
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      trustManagerFactory.init(keyStore); 
      sslContext.init(null,trustManagerFactory.getTrustManagers(), new SecureRandom()); 
      client.setSslSocketFactory(sslContext.getSocketFactory()); 
     } catch (Exception e) { 
      Log.d("AppName", "cannot create http client", e); 
     } 

SSLUtils класс:

import android.content.Context; 
import android.content.res.AssetManager; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.io.InputStream; 
import java.security.KeyStore; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateFactory; 
import java.security.cert.X509Certificate; 

public class SSLUtils { 

    private static final Logger LOG = LoggerFactory.getLogger(SSLUtils.class.getSimpleName()); 

    public static KeyStore getKeyStore(Context context) { 
     KeyStore keyStore = null; 
     try { 
      AssetManager assetManager = context.getAssets(); 
      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      InputStream caInput = assetManager.open("cert.pem"); 
      Certificate ca; 
      try { 
       ca = cf.generateCertificate(caInput); 
       LOG.debug("ca={}", ((X509Certificate) ca).getSubjectDN()); 
      } finally { 
       caInput.close(); 
      } 

      String keyStoreType = KeyStore.getDefaultType(); 
      keyStore = KeyStore.getInstance(keyStoreType); 
      keyStore.load(null, null); 
      keyStore.setCertificateEntry("ca", ca); 
     } catch (Exception e) { 
      LOG.error("Error during getting keystore", e); 
     } 
     return keyStore; 
    } 
} 

Поместите свой файл cert.pem в assets каталоге.
Я использую slf4android для регистрации, но вы, конечно, можете использовать стандартный класс Log.

Надеюсь, что это вам поможет :)

+0

Спасибо за ответ! Мне кажется, что наши фрагменты почти одинаковы, за исключением расширения сертификата. Я пробовал с .pem, но это тоже не сработало :( – mol

+0

@mol его не имеет большого значения;) http://stackoverflow.com/questions/4691699/how-to-convert-crt-to-pem – mklimek

+0

да, я уже пробовал, такое же исключение. – mol

Смежные вопросы