2015-06-08 88 views
0

我試圖將HTTP請求發送到使用SSL進行保護的應用程序服務器。我有一個來自服務器團隊的自簽名X.509證書。我跟着從documentation教程,但還是得到了SSLHandshakeExceptionjava.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

相關問題