2013-01-01 15 views
14

Próbuję utworzyć połączenie HTTPS z numerem server, którego zestaw certyfikatów wygasa w kwietniu 2013 r. I używa GlobalSign jako głównego certyfikatu.Tworzenie połączenia HTTPS przy użyciu adresu URL.openConnection()

HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); 
// urlConnection.setSSLSocketFactory(sslSocketFactory); 
urlConnection.setDoOutput(true); 
urlConnection.setChunkedStreamingMode(0); 

// Send the POST data 
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); 
out.write(postParamString.toString().getBytes("UTF8")); 

// Read the reply 
InputStream in = urlConnection.getInputStream(); 

W obecnej formie, to rzuca javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. gdy getOutputStream() nazywa.

Ta sama strona i certyfikat są ważne w zapasowej przeglądarce HTC i przeglądarkach komputerowych. Kiedy używam tego samego kodu, aby uzyskać dostęp do Google, działa (ale potem narzeka na błąd 404). Różne posty na StackOverflow sugerują, że powinna "po prostu działać", a inni mówią, aby skonfigurować własny magazyn kluczy (lub wyłączyć wszystkie walidacje HTTPS!) Zakładam, że różnica w zachowaniu zależy od różnych używanych magazynów kluczy głównych (Czy ktoś może to wyjaśnić? ?).

Próbowałem już stworzyć kluczowy sklep z dmuchanym zamkiem, ale nie mogę go załadować na moje urządzenie.

Po wyeksportowaniu certyfikat z Firefox utworzyć magazyn kluczy przy użyciu:

keytool.exe -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -keystore res\raw\keystore 

ta jest następnie załadowane i wykorzystywane w aplikacji za pomocą:

InputStream stream = context.getResources().openRawResource(R.raw.keystore); 
// BKS seems to be the default but we want to be explicit 
KeyStore ks = KeyStore.getInstance("BKS"); 
ks.load(stream, "www.onlinescoutmanager.co.uk".toCharArray()); 
stream.close(); 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init(ks); 
X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; 
SSLContext context2 = SSLContext.getInstance("TLS"); 
context2.init(null, new TrustManager[] { defaultTrustManager }, null); 
sslSocketFactory = context2.getSocketFactory(); 

to niepowodzeniem z java.io.IOException: Wrong version of key store. gdy keystore.Load() jest nazywany.

Posiadam ensured I'm passing -storetype BKS, used a <=7 character keystore password, dodałem certyfikaty CA do magazynu kluczy i używam obu wersji Bouncy Castle w wersji 1.45 i 1.47 do utworzenia magazynu kluczy bez zmian w zgłoszonym komunikacie o błędzie.

Moje środowisko to Eclipse Juno 4.2.1 z oprogramowaniem JRE 1.7u9b5 działającym pod kontrolą systemu Windows 8. Urządzenie, na którym testuję, to urządzenie HTC z systemem Android 2.3. Aplikacja ma minimalną wersję SDK 7 i cel 15.

Jeśli ktokolwiek może wyjaśnić, jak utworzyć prawidłowy magazyn kluczy BKS w systemie Windows 8 lub jak uzyskać Javę do korzystania z tego samego magazynu kluczy co przeglądarka (lub system?), który byłby doceniony.

Możesz pobrać entire project, tak jak to było w czasie pisania, i generated keystore, jeśli jest to wymagane.

+2

To zdecydowanie najlepsze sformułowane pytanie, jakie kiedykolwiek widziałem, na każdej stronie. –

+0

@AndreaLigios Musiałem odpowiedzieć na nieliczne, powinienem znać zasady i jak "zadać przyzwoite pytanie": p – Deanna

+0

@ Deanna, kiedy tworzysz magazyn kluczy, czy powinieneś -trustedcacerts w opcjach, aby sprawdził poprawność certyfikatu za pomocą zaufanych certyfikatów? (Neve pracował z odgadywaniem BKS opartym na podobieństwach jądra Java) –

Odpowiedz

2

Bouncy Castle 1.47 używa innego nagłówka wersji. Czy możesz spróbować 1.46 version, to powinno działać.

keytool -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -storepass osmosm -keystore C:/keystore -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-ext-jdk15on-1.46.jar 
+0

Używam już 1.45 (użyłem początkowo 1.47, zobacz pytanie) czy 1.46 coś zmieni? Pamiętaj, że aktualnie wybieram system Android 2.3, który wydaje się używać wersji 1.45. – Deanna

+0

Hmmm, nie próbowałem wersji 1.45, ale mogę powiedzieć, że Twój projekt pomyślnie ładuje magazyn kluczy utworzony przez wersję 1.46. – Akdeniz

+0

Tutaj jest: http://dl.dropbox.com/u/26734922/keystore – Akdeniz

3

Dzięki różnym ludziom dla ich wskazówek dotyczących tego, istnieje wiele rzeczy, które wszystkie musiały być poprawne dla go do pracy.

  1. Jeśli certyfikat witryny HTTPS jest podpisane przez zaufanego certyfikatu głównego to będzie działać po wyjęciu z pudełka, bez zwyczaju SSLSocketFactory. Zaufane certyfikaty główne mogą różnić się od tych używanych przez przeglądarkę, więc nie zakładaj, że jeśli działają one w przeglądarce internetowej Androida, to będą działać w Twojej aplikacji.
    Jeśli nie jest to zaufany certyfikat główny, a otrzymasz wyjątki, takie jak javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature., musisz utworzyć i załadować magazyn kluczy, jak poniżej.

  2. magazynu kluczy musi być generowane przy użyciu dostawcy Bouncy Castle (1) określając -storetype bks w wierszu poleceń keytool.
    Jeśli dmuchany zamek nie jest zainstalowany prawidłowo, spowoduje to niepowodzenie z różnymi wyjątkami, w tym java.security.KeyStoreException: BKS not found. Jeśli magazyn kluczy nie zostanie utworzony u dostawcy zamków Bouncy Castle, może pojawić się wyjątek java.io.IOException: Wrong version of key store., powodujący zamieszanie w następnym przypadku.

  3. Musisz użyć odpowiedniej wersji (1, 2, 3) dostawcy Zamku Bouncy. W większości przypadków wygląda to na version 1.46.
    Można to umieścić w folderze JRE lib/ext/, a nazwę klasy dodać do lib/security/java.security lub podać bezpośrednio w wierszu poleceń pod numerem keytool. Jeśli jest to niekompatybilna wersja (lub typ sklepu), ponownie uzyskasz wyjątki zgodne z java.io.IOException: Wrong version of key store..

  4. Należy uwzględnić wszystkich pośredników i certyfikat główny. Jeśli czegoś brakuje, otrzymasz wyjątek od javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found..

  5. Łańcuch certyfikatów MUSI być w celu ich poprawnej weryfikacji. Jeśli tak nie jest, to albo otrzymasz numer javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: IssuerName(CN=XYZ) does not match SubjectName(CN=ABC) of signing certificate., albo ponownie, rodzajowy javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Nie znalazłem sposobu zamówienia ich w magazynie kluczy, więc uciekłem się do doing it in code at runtime.

Niektórzy sugerują, że using a keystore password longer than 7 characters będzie również spowodować, że nie, ale to nie to, co znalazłem.

Myślę, że obejmuje to każdą pułapkę, jaką znalazłem, ale nie krępuj się poszerzać i dodawać linsk do powiązanych pytań.

Powiązane problemy