2013-10-17 10 views
9

का उपयोग कर एंड्रॉइड एसएसएल HTTP अनुरोध मेरे पास एक एंड्रॉइड एप्लिकेशन है जो हम होस्ट करते हुए एक एसएसएल वेब सेवा से कनेक्ट हो रहा है। वेब सर्वर अपाचे है और इसका अपना सीए है जिसे हमने बनाया है और स्वयं हस्ताक्षरित SSL प्रमाण पत्र है।स्व-हस्ताक्षरित प्रमाणपत्र और सीए

मैंने सुरक्षा में उपयोगकर्ता विश्वसनीय प्रमाणपत्र अनुभाग में एंड्रॉइड टैबलेट पर हमारे सीए प्रमाण पत्र आयात किए हैं।

मैं वेब सर्वर तक पहुँच परीक्षण किया है और इस बात की पुष्टि कर सकते हैं कि वेब सेवा प्रमाण पत्र के रूप में मान्य (स्क्रीनशॉट नीचे) से पता चलता

Valid certificate

यहाँ सुरक्षा सेटिंग में प्रमाण पत्र है:

Trusted certificate

अब जब मैं अपने आवेदन में webservice को आजमाता हूं और एक्सेस करता हूं तो मुझे "नो पीयर सर्टिफिकेट" अपवाद ट्रिगर किया जाता है।

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // allows network on main thread (temp hack) 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 

    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    //schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 
    schemeRegistry.register(new Scheme("https", newSSLSocketFactory(), 443)); 


    HttpParams params = new BasicHttpParams(); 

    SingleClientConnManager mgr = new SingleClientConnManager(params, schemeRegistry); 

    HttpClient client = new DefaultHttpClient(mgr, params); 

    HttpPost httpRequest = new HttpPost("https://our-web-service.com"); 

    try { 
     client.execute(httpRequest); 
    } catch (Exception e) { 
     e.printStackTrace(); // 
    } 
} 

/* 
* Standard SSL CA Store Setup // 
*/ 
private SSLSocketFactory newSSLSocketFactory() { 

    KeyStore trusted; 

    try { 
     trusted = KeyStore.getInstance("AndroidCAStore"); 
     trusted.load(null, null); 
     Enumeration<String> aliases = trusted.aliases(); 

     while (aliases.hasMoreElements()) { 
      String alias = aliases.nextElement(); 
      X509Certificate cert = (X509Certificate) trusted.getCertificate(alias); 
      Log.d("", "Alias="+alias); 
      Log.d("", "Subject DN: " + cert.getSubjectDN().getName()); 
      Log.d("", "Issuer DN: " + cert.getIssuerDN().getName()); 
     }  

     SSLSocketFactory sf = new SSLSocketFactory(trusted); 
     sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); 

     return sf; 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     throw new AssertionError(e); 
    } 
} 

} 

जबकि पाश सिर्फ प्रमाण पत्र बाहर थूक और मैं लॉग में अपने ही सीए देख सकते हैं:

यह SSL कार्यान्वयन को सरल बनाया है। लेकिन मुझे अभी भी "नो पीयर सर्टिफिकेट" अपवाद मिलता है।

10-17 18: 29: ०१.२३४: मैं/System.out (4006): नहीं सहकर्मी प्रमाण पत्र

मैं मैन्युअल रूप से इस कार्यान्वयन में किसी भी तरह मेरी CA प्रमाणपत्र लोड करने के लिए है?

+0

आप इस कार्यान्वयन में अपने CA प्रमाणपत्र लोड हो रहा है मैन्युअल रूप से करने की कोशिश की है? – BON

+0

आप अपने डोमेन के लिए http://www.startssl.com/ (मैं उन्हें कुछ ऐप्स के लिए उपयोग कर रहा हूं) से एक नि: शुल्क और भरोसेमंद SSL प्रमाण पत्र प्राप्त कर सकता हूं, इसलिए आपको हर डिवाइस में अपना सीए जोड़ने से निपटने की ज़रूरत नहीं है जो आपके ऐप का उपयोग करना चाहता है। –

उत्तर

4

का उपयोग करके हल: HttpsURLConnection

URLConnection conn = null; 
URL url = new URL(strURL); 
conn = url.openConnection(); 
HttpsURLConnection httpsConn = (HttpsURLConnection) conn; 

इस उपयोगकर्ता स्थापित CA प्रमाणपत्रों के साथ ठीक से काम करने लगता है।

2

तुम भी, DefaultHttpClient का उपयोग कर भी here is suggested हालांकि कार्य पूरा कर सकते हैं:

आयात करने या अपने आवेदन करने के लिए प्रमाणपत्र जोड़ने जब से तुम हो सकता है में नए कोड के लिए पसंद करते हैं HttpURLConnection

वेतन ध्यान भी सर्टिफिकेट को अपडेट करने में समस्याएं समाप्त हो जाएंगी।

* This method returns the appropriate HttpClient. 
* @param isTLS Whether Transport Layer Security is required. 
* @param trustStoreInputStream The InputStream generated from the BKS keystore. 
* @param trustStorePsw The password related to the keystore. 
* @return The DefaultHttpClient object used to invoke execute(request) method. 
private DefaultHttpClient getHttpClient(boolean isTLS, InputStream trustStoreInputStream, String trustStorePsw) 
    throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException { 
    DefaultHttpClient client = null;   
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 8080); 
    schemeRegistry.register(http); 
    if(isTLS) { 
     KeyStore trustKeyStore = null; 
     char[] trustStorePswCharArray = null; 
     if(trustStorePsw!=null) { 
      trustStorePswCharArray = trustStorePsw.toCharArray(); 
     } 
     trustKeyStore = KeyStore.getInstance("BKS"); 
     trustKeyStore.load(trustStoreInputStream, trustStorePswCharArray); 
     SSLSocketFactory sslSocketFactory = null; 
     sslSocketFactory = new SSLSocketFactory(trustKeyStore); 
     Scheme https = new Scheme("https", sslSocketFactory, 8443); 
     schemeRegistry.register(https); 
    }     
    HttpParams httpParams = new BasicHttpParams(); 
    HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT); 
    HttpConnectionParams.setSoTimeout(httpParams, SOCKET_TIMEOUT);   
    ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);   
    client = new DefaultHttpClient(clientConnectionManager, httpParams);   
    return client; 
} 

और यहाँ कैसे प्राप्त करने के लिए एक HttpsURLConnection:

यहाँ कैसे एक DefaultHttpClient पर भरोसा करने के लिए एक स्व-हस्ताक्षरित प्रमाणपत्र प्राप्त करने के लिए

* This method set the certificate for the HttpsURLConnection 
* @param url The url to contact. 
* @param certificateInputStream The InputStream generated from the .crt certificate. 
* @param certAlias The alias for the certificate. 
* @return The returned HttpsURLConnection 
private HttpsURLConnection getHttpsURLConnection(URL url, InputStream certificateInputStream, String certAlias) 
    throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { 
    HttpsURLConnection connection = null; 
    CertificateFactory certFactory = null; 
    Certificate cert = null; 
    KeyStore keyStore = null; 
    TrustManagerFactory tmFactory = null; 
    SSLContext sslContext = null; 
    // Load certificates from an InputStream 
    certFactory = CertificateFactory.getInstance("X.509"); 
    cert = certFactory.generateCertificate(certificateInputStream); 
    certificateInputStream.close(); 
    // Create a KeyStore containing the trusted certificates 
    keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    keyStore.load(null, null); 
    keyStore.setCertificateEntry(certAlias, cert); 
    // Create a TrustManager that trusts the certificates in our KeyStore 
    tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmFactory.init(keyStore); 
    // Create an SSLContext that uses our TrustManager 
    sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(null, tmFactory.getTrustManagers(), null); 
    connection = (HttpsURLConnection)url.openConnection(); 
    connection.setSSLSocketFactory(sslContext.getSocketFactory()); 
    return connection; 
} 
संबंधित मुद्दे