2013-01-01 16 views
14

Sto cercando di stabilire una connessione HTTPS a server con un certificato scaduto nell'aprile 2013 e utilizza GlobalSign come certificato di origine.Creazione di una connessione HTTPS mediante 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(); 

Così com'è, questo getta javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. quando getOutputStream() si chiama.

Questo stesso sito e certificato sono validi nel browser Web HTC e nei browser desktop. Quando uso lo stesso codice per accedere a Google funziona (ma poi si lamenta di un errore 404). Vari post su StackOverflow implicano che dovrebbe "funzionare" e altri dicono di impostare il proprio keystore (o disabilitare tutte le convalide HTTPS!). Presumo che la differenza di comportamento sia dovuta a diversi keystore in uso (Qualcuno può chiarire questo ?).

Ora ho provato a creare un keystore utilizzando bouncy castle ma non riesco a farlo caricare sul mio dispositivo.

Dopo l'esportazione del certificato da Firefox, creo un archivio chiavi utilizzando:

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

Questo viene poi caricata e utilizzata nell'applicazione utilizzando:

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

Questo sta venendo a mancare con java.io.IOException: Wrong version of key store. quando keystore.Load() è chiamato.

Ho ensured I'm passing -storetype BKS, used a <=7 character keystore password, aggiunto i certificati CA all'archivio chiavi e utilizzando entrambi i modelli Bouncy Castle 1.45 e 1.47 per creare l'archivio chiavi senza modifiche nel messaggio di errore segnalato.

Il mio ambiente è Eclipse Juno 4.2.1 con JRE 1.7u9b5 in esecuzione su Windows 8. Il dispositivo su cui sto eseguendo il test è HTC sensazione in esecuzione Android 2.3. L'applicazione ha una versione SDK minima di 7 e un target di 15.

Se qualcuno può spiegare come creare un key store BKS valido su Windows 8 o come posso ottenere Java per utilizzare lo stesso keystore del browser (o sistema?) che sarebbe apprezzato.

È possibile scaricare entire project come al momento della scrittura e il generated keystore se necessario.

+2

Questa è sicuramente la migliore domanda formulata che abbia mai visto, su qualsiasi sito –

+0

@AndreaLigios Ho dovuto rispondere a pochissimi, dovrei conoscere le regole e come "porre una domanda decente": p – Deanna

+0

@ Deanna quando crei il keystore, dovresti avere -trustedcacerts nelle opzioni in modo che convalidi il certificato usando i certificati attendibili? (Neve ha funzionato con la supposizione di BKS basata su somiglianze java di base) –

risposta

2

Bouncy Castle 1.47 utilizza un'intestazione di versione diversa. Puoi provare 1.46 version, dovrebbe funzionare.

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

Sto già usando 1.45 (ho usato 1.47 inizialmente, vedi la domanda) 1.46 farà la differenza? Ricorda che al momento utilizzo Android 2.3 che sembra utilizzare 1.45. – Deanna

+0

Hmmm, non ho provato con la versione 1.45, ma posso dire che il tuo progetto carica con successo il keystore creato dalla versione 1.46. – Akdeniz

+0

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

3

Grazie a varie persone per i loro suggerimenti su questo, ci sono più cose che tutti avevano bisogno di essere corretti per farlo funzionare.

  1. Se il certificato del sito HTTPS è firmato da un certificato principale attendibile allora funzionerà fuori dalla scatola, senza una consuetudine SSLSocketFactory. I certificati radice attendibili possono essere diversi da quelli utilizzati da un browser, quindi non dare per scontato che, se funziona nel browser web Android, funzionerà nella tua app.
    Se non è un certificato radice attendibile e si ottengono eccezioni come javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature., è necessario creare e caricare un keystore come di seguito.

  2. Il keystore deve essere generato utilizzando il provider Bouncy Castle (1) specificando -storetype bks sulla riga di comando keytool.
    Se Bouncy Castle non è installato correttamente, ciò avrà esito negativo con varie eccezioni, tra cui java.security.KeyStoreException: BKS not found. Se il keystore non viene creato con il provider di Bouncy Castle, è possibile che si verifichi l'eccezione java.io.IOException: Wrong version of key store., causando confusione con il caso successivo.

  3. è necessario utilizzare una versione appropriata (1, 2, 3) del provider Castello gonfiabile. Nella maggior parte dei casi, sembra essere version 1.46.
    Questo può essere inserito nella cartella lib/ext/ di JRE e il nome classe aggiunto a lib/security/java.security o specificato direttamente nella riga di comando su keytool. Se si tratta di una versione incompatibile (o tipo di negozio), si otterranno di nuovo delle eccezioni sulla linea java.io.IOException: Wrong version of key store..

  4. È necessario includere tutti gli intermediari e il certificato di origine. Se mancano alcuni, si riceverà un'eccezione javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found..

  5. La catena di certificati DEVE essere in ordine per essere convalidati correttamente. Se non lo sono, otterrete javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: IssuerName(CN=XYZ) does not match SubjectName(CN=ABC) of signing certificate. o di nuovo, un generico javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Non ho trovato un modo per ordinarli nell'archivio delle chiavi in ​​modo da ricorrere a doing it in code at runtime.

Alcune persone hanno suggerito che using a keystore password longer than 7 characters sarà anche causare il fallimento, ma non è quello che ho trovato.

Penso che questo copra ogni trappola che ho trovato, ma sentitevi libero di espandere e aggiungere linsk alle domande correlate.

Problemi correlati