2012-09-10 13 views
8

HttpsUrlConnection nesnesini kullanarak basit bir OpenSSL sunucusuna bağlanmak için Android alıyorum sorun yaşıyorum (StackOverflow ve çevrimiçi öğreticiler demet, ve hat için oldukça fazla çizgi takip ve hala benim yerel güven mağaza kullandığımda neden benim kırık olduğunu anlayamıyorum).Android HttpsUrlConnection javax.net.ssl.SSLException Yerel güven deposunu kullanırken eşdüzey sıkışma hatasıyla kapatılan bağlantı

Şu anda bağlanmayı dener bir Android aktiviteye sahip

basit OpenSSL serverHttpsUrlConnection.connect() denir kez ben yanlış bir "javax.net.ssl.SSLException: Connection closed by peer" error during the SSL handshake. Belki kuruyorum benim örnek sunucusunu almak, (Ben OpenSSL istemcisi kullanarak benim sunucusuna bağlanabilir) ?

Unutulmaması gereken nokta:

  • an varsayılan güven deposu
  • yüklerken https://www.google.com bağlanabiliyor
  • am hiç müşteri yetkilendirme
  • tüm sertifikalara güvenmek istemiyorum kendinden imzalı sertifika ile localhost üzerinde sunucuya bağlanabiliyor değilim
  • sadece
  • yerel oluşturulan yerel truststore kullanmak istediğiniz Apache HttpClient kullanmak istemiyoruz şişme kale düzgün bir proxy güvenlik duvarı arkasında
  • içine truststore yükleyebildiğinden
  • am ile truststore, vekil
  • AVDayarlı benim android sanal cihazda ayarlanır.

şeyler zaten denedi:

  • 'URL u = new URL("https", "10.0.2.2", 443, "/");'
  • TrustManagerFactory.getDefaultAlgorithms() kullanarak yerine "X509"
      ile URL oluşturma yeni SecureRandom() with the SSLContext.init()
    • kullanarak hem 127.0.0.1 and 10.0.2.2
    • bağlanırken
    • yerine "Unexpected response code error 503" arasında
  • "Bağlantı eş tarafından kapatıldı"

sorumu incelemek üzere zaman ayırdığınız için şimdiden teşekkür ederiz! komutuyla test

$ sudo openssl s_server -accept 443 -cert server-cert.pem -key server-key.pem -pass file:passphrase.txt -state -www -verify 0 

Müşteri bağlantısı:

Basit sunucu komutuyla başlayan

$ openssl s_client -connect 127.0.0.1:443 

Android etkinlik kodu (basitleştirme için tam koşu kodu kaldırmak için düzenlenmiş - bana daha kod eğer bildirin gerekli) - hata çıkışı kodun altında.https://www.google.com doğru bağlayan

try { 
     TrustManagerFactory tmf; 

     // local trust store 
     tmf = TrustManagerFactory.getInstance("X509"); 
     tmf.init(loadLocalKeyStore(getApplicationContext())); 

     // default trust store - works for https://www.google.com 
     // tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     // tmf.init((KeyStore) null); 

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

     HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER; 
     URL u = new URL("https://10.0.2.2"); 

     HttpsURLConnection urlConnection = (HttpsURLConnection) u.openConnection(); 

     urlConnection.setSSLSocketFactory(context.getSocketFactory()); 
     urlConnection.setHostnameVerifier(hostnameVerifier); 
     urlConnection.connect(); 

     System.out.println("Response Code: " + urlConnection.getResponseCode()); 
     System.out.println("Response Code: " + urlConnection.getCipherSuite()); 
    } 

    ... 

    private KeyStore loadLocalKeyStore(Context context) { 
     InputStream in = context.getResources().openRawResource(R.raw.newserverkeystore); 
     KeyStore trusted = null; 
     try { 
      trusted = KeyStore.getInstance("BKS"); 
      trusted.load(in, "thisisasecret".toCharArray()); 
     } finally { 
      in.close(); 
     } 
     return trusted; 
    } 

Çıktı:

09-09 21:58:09.947: I/System.out(669): Response Code: 200 
09-09 21:58:09.947: I/System.out(669): Response Code: TLS_ECDHE_RSA_WITH_RC4_128_SHA 

Çıktı otomatik olarak imzalanan sertifika ile benim sunucuya bağlanmaya çalışırken: Yeniden

09-09 22:03:23.377: D/HttpsProxy(717): Https Request error 
09-09 22:03:23.377: D/HttpsProxy(717): javax.net.ssl.SSLException: Connection closed by peer 
09-09 22:03:23.377: D/HttpsProxy(717): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) 
09-09 22:03:23.377: D/HttpsProxy(717): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:395) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:442) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 
09-09 22:03:23.377: D/HttpsProxy(717): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:165) 
09-09 22:03:23.377: D/HttpsProxy(717): at com.example.myfirstapp.HttpsUrlConnectionActivity$3.doInBackground(HttpsUrlConnectionActivity.java:257) 
09-09 22:03:23.377: D/HttpsProxy(717): at com.example.myfirstapp.HttpsUrlConnectionActivity$3.doInBackground(HttpsUrlConnectionActivity.java:1) 
09-09 22:03:23.377: D/HttpsProxy(717): at android.os.AsyncTask$2.call(AsyncTask.java:287) 
09-09 22:03:23.377: D/HttpsProxy(717): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
09-09 22:03:23.377: D/HttpsProxy(717): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
09-09 22:03:23.377: D/HttpsProxy(717): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
09-09 22:03:23.377: D/HttpsProxy(717): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
09-09 22:03:23.377: D/HttpsProxy(717): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
09-09 22:03:23.377: D/HttpsProxy(717): at java.lang.Thread.run(Thread.java:856) 

Teşekkür !!

+0

Android emülatörüne bağlanmaya çalıştığımda, yalnızca OpenSSL istemcim ile herhangi bir sunucu etkinliğini görmediğimi belirtmeyi unuttum. – aspergillusOryzae

+0

bu soruyu biçimlendirmek çok zor ;-) –

+0

Maalesef, soruya oy vermeden önce daha kolay anlaşılabilmenin bir yolu var mı? Yeniden yönlendirilmeden önce diğer yayınlardan aldığım yöntemleri açıklamaya çalışıyordum. – aspergillusOryzae

cevap

6

Sorunumu çözdüm - 10.0.2.2 olan bir sertifikayı genel adı (CN) olarak kullanmam gerekiyordu, bu nedenle 'localhost' veya '127.0.0.1' yerine 10.0.2.2 değerinin Android localhost ip adresi ile eşleşti.

Düzenleme: büyük olasılıkla localhost ile CN ve '127.0.0.1' ve '10 .0.2.2 'gibi bir konu oluşturabilir ve konu Alternatif Adlar (SAN) olarak oluşturabilirsiniz. Ben 10.0.2.2 sertifika ve özel anahtar pem dosyalarını oluşturulan kez

, benim sunucusu aşağıdaki komutla çalışan vurmak başardı: (olsa da bir sertifika sağlamak müşteri zorlamak istiyorsanız

openssl s_server -accept 8888 -cert 10.0.2.2-cert.pem -key 10.0.2.2-key.pem -state -www 

kontrol edilmeyecektir), yukarıdaki komuta bayrağı -Verify 1 ekleyin.

aşağıdaki kullanabileceğiniz komut satırında sunucuyu test etmek için (not openssl 127.0.0.1 üzerinden bağlanmak yapabiliyor):

openssl s_client -connect 127.0.0.1:8888 

Ve sunucu gerektiriyorsa bir istemci sertifika eklemek için, eklemek

// use local trust store (CA) 
TrustManagerFactory tmf; 
KeyStore trustedStore = null; 
InputStream in = context.getResources().openRawResource(R.raw.mycatruststore); // BKS in res/raw 
trustedStore = KeyStore.getInstance("BKS"); 
trustedStore.load(in, "insertBksPasswordHere".toCharArray()); 
tmf = TrustManagerFactory.getInstance("X509"); 
tmf.init(trustedStore); 

// load client certificate 
KeyStore clientKeyStore = loadClientKeyStore(getApplicationContext()); 
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); 
kmf.init(clientKeyStore, "insertPasswordHere".toCharArray()); 

SSLContext context = SSLContext.getInstance("TLS"); 

// provide client cert - if server requires client cert this will pass 
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER; 

// connect to url 
URL u = new URL("https://10.0.2.2:8888/"); 
HttpsURLConnection urlConnection = (HttpsURLConnection) u.openConnection(); 
urlConnection.setSSLSocketFactory(context.getSocketFactory()); 
urlConnection.setHostnameVerifier(hostnameVerifier); 
urlConnection.connect(); 
System.out.println("Response Code: " + urlConnection.getResponseCode()); 

Sen 2 'lik bir yanıt kodu almalısınız: my Android istemcisi olarak bayraklar -cert client-cert.pem -key client-key.pem

Ben (hata kaldırıldı Kontrolden) bağlamak için aşağıdaki kodu kullanılmış 00, ve oradan yanıtı dağıtabilir. 7 saat nihayet bu sorunu sabit ve - benim 6

private KeyStore loadClientKeyStore(Context context) { 
    InputStream in = context.getResources().openRawResource(R.yourKeyStoreFile); 
    KeyStore trusted = null; 
    trusted = KeyStore.getInstance("BKS"); 
    trusted.load(in, "yourClientPassword".toCharArray()); 
    in.close(); 
    return trusted; 
} 
2

Ben boşa: Burada

sunucu anahtar deposunu yükleme için ama farklı bir kaynak dosya adı ve parola ile aynıdır istemci kimlik bilgilerini yüklemek için kodu var

ile çalıştı ve işe yaradı !!!!!!

İlgili konular