2013-01-01 23 views
14

Ich versuche, eine HTTPS-Verbindung zu einem server herzustellen, dessen Zertifikat im April 2013 abgelaufen ist und das GlobalSign als Stammzertifikat verwendet.Herstellen einer HTTPS-Verbindung mithilfe von 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(); 

Wie es aussieht, dies wirft javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. wenn getOutputStream() genannt wird.

Die gleiche Website und das gleiche Zertifikat sind im HTC Webbrowser und Desktop-Browser gültig. Wenn ich den gleichen Code verwende, um auf Google zuzugreifen, funktioniert es (aber beschwert sich dann über einen 404-Fehler). Verschiedene Posts auf StackOverflow implizieren, dass es "einfach funktioniert" und andere sagen, dass Sie Ihren eigenen Schlüsselspeicher einrichten (oder alle HTTPS-Validierung deaktivieren!) Ich nehme an, der Unterschied im Verhalten ist auf verschiedene Stammschlüssel speichert im Einsatz (Kann jemand dies klären ?).

Ich habe jetzt versucht, einen Schlüsselspeicher mit Hüpfburg zu erstellen, aber ich kann das nicht auf meinem Gerät laden.

Nachdem das Zertifikat von Firefox exportieren, erstelle ich einen Schlüsselspeicher mit:

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

Dies wird dann in der Anwendung geladen und verwendet werden:

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(); 

Dies wird mit java.io.IOException: Wrong version of key store. versagt, wenn keystore.Load() wird genannt.

Ich habe ensured I'm passing -storetype BKS, used a <=7 character keystore password, die CA-Zertifikate in den Schlüsselspeicher hinzugefügt, und beide Bouncy Castle Version 1.45 und 1.47 verwenden, um den Schlüsselspeicher ohne Änderung in der gemeldeten Fehlermeldung zu erstellen.

Meine Umgebung ist Eclipse Juno 4.2.1 mit JRE 1.7u9b5 unter Windows 8. Das Gerät, das ich testen, ist ein HTC Sensation laufenden Lager Android 2.3. Die Anwendung hat eine SDK-Mindestversion von 7 und ein Ziel von 15.

Wenn jemand erklären kann, wie ein gültiger BKS-Schlüsselspeicher unter Windows 8 erstellt wird oder wie ich Java dazu bringen kann, denselben Schlüsselspeicher wie den Browser zu verwenden (oder System?) das würde geschätzt werden.

Sie können die entire project zum Zeitpunkt des Schreibens und die generated keystore bei Bedarf herunterladen.

+2

Dies ist definitiv die am besten formulierte Frage, die ich je gesehen habe, auf jeder Seite –

+0

@AndreaLigios Ich habe ein paar weit zu beantworten, ich sollte die Regeln kennen und wie man eine anständige Frage "p Frage – Deanna

+0

@ Deanna, wenn Sie den Schlüsselspeicher erstellen, sollten Sie -trustedcacerts in den Optionen haben, damit das Zertifikat mit den vertrauenswürdigen Zertifikaten validiert wird? (Neve arbeitete mit BKS Raten basierend auf Core Java Ähnlichkeiten) –

Antwort

2

Bouncy Castle 1.47 verwendet verschiedene Version Header. Können Sie versuchen 1.46 version, sollte es funktionieren.

+0

Ich benutze bereits 1,45 (Ich habe anfangs 1,47 verwendet, siehe Frage) wird 1,46 einen Unterschied machen? Denken Sie daran, dass ich derzeit auf Android 2.3 ziele, das 1,45 zu verwenden scheint. – Deanna

+0

Hmmm, ich habe nicht mit 1.45 Version versucht, aber ich kann sagen, dass Ihr Projekt erfolgreich Keystore von 1,46-Version erstellt geladen. – Akdeniz

+0

Hier ist es: http://dl.dropbox.com/u/26734922/keystore – Akdeniz

3

Dank verschiedener Leute für ihre Hinweise darauf, gibt es mehrere Dinge, die alle richtig sein mussten, damit es funktioniert.

  1. Wenn das Zertifikat der HTTPS-Site von einem vertrauenswürdigen Root-Zertifikat signiert ist, dann wird es ohne einen kundenspezifische SSLSocketFactory aus dem Kasten heraus zu arbeiten. Die vertrauenswürdigen Stammzertifikate können sich von denen unterscheiden, die von einem Browser verwendet werden. Gehen Sie also nicht davon aus, dass es in Ihrer App funktioniert, wenn es im Android-Webbrowser funktioniert.
    Wenn es sich nicht um ein vertrauenswürdiges Stammzertifikat handelt und Sie Ausnahmen wie javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. erhalten, müssen Sie einen Schlüsselspeicher wie folgt erstellen und laden.

  2. Der Schlüsselspeicher muss erzeugt werden, um den Hüpfburg Provider (1) durch -storetype bks auf der keytool Befehlszeile angeben.
    Wenn Hüpfburg nicht korrekt installiert ist, wird dies mit verschiedenen Ausnahmen einschließlich java.security.KeyStoreException: BKS not found fehlschlagen. Wenn der Schlüsselspeicher nicht mit dem Bouncy Castle-Anbieter erstellt wird, erhalten Sie möglicherweise die Ausnahme java.io.IOException: Wrong version of key store., was zu Verwechslungen mit dem nächsten Fall führt.

  3. Sie müssen eine geeignete Version (1, 2, 3) des Bouncy Castle-Anbieters verwenden. In den meisten Fällen scheint dies version 1.46 zu sein.
    Dies kann in den Ordner lib/ext/ Ihres JREs eingefügt werden und der Klassenname wird zu lib/security/java.security hinzugefügt oder direkt in der Befehlszeile zu keytool angegeben. Wenn es sich um eine inkompatible Version (oder einen Geschäftstyp) handelt, erhalten Sie wieder Ausnahmen in der Form java.io.IOException: Wrong version of key store..

  4. Sie müssen alle Vermittler und das Stammzertifikat einschließen. Wenn irgendwelche fehlen, erhalten Sie eine Ausnahme.

  5. Die Zertifikatskette MUSS in Ordnung sein, damit sie korrekt validiert werden können. Wenn Sie nicht sind, erhalten Sie entweder javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: IssuerName(CN=XYZ) does not match SubjectName(CN=ABC) of signing certificate. oder wieder, eine generische Ich habe keinen Weg gefunden, um sie im Schlüsselspeicher so auf doing it in code at runtime Zuflucht genommen.

Einige Leute haben vorgeschlagen, dass using a keystore password longer than 7 characters wird es auch nicht dazu führen, aber das ist nicht das, was ich gefunden habe.

Ich denke, dies deckt jede Fallgrube, die ich gefunden habe, aber fühlen Sie sich frei zu erweitern und hinzufügen Linsk zu verwandten Fragen.

Verwandte Themen