2012-05-14 1 views
0

Chaque fois que je tente de poster à un point de terminaison https, je reçois un javax.net.ssl.SSLException: java.lang.NullPointerException:Comment puis-je faire un HttpPost en utilisant HttpClient à un point de terminaison HTTPS?

import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; 
import org.apache.commons.httpclient.methods.GetMethod; 
import org.apache.commons.httpclient.HttpClient; 

try { 
    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 
    HttpClient httpClient = new HttpClient(connectionManager); 
    PostMethod pm = new PostMethod("https://www.random.org"); 
    httpClient.executeMethod(pm); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

Ce qui me donne:

javax.net.ssl.SSLException: java.lang.NullPointerException 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1692) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1675) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1601) 
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:94) 
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) 
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) 
    at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828) 
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1565) 
    at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116) 
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) 
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) 
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) 
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) 
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) 
    at <My File> 
Caused by: java.lang.NullPointerException 
    at org.bouncycastle.jce.provider.JCEECPublicKey.<init>(Unknown Source) 
    at org.bouncycastle.jce.provider.JDKKeyFactory.createPublicKeyFromPublicKeyInfo(Unknown Source) 
    at org.bouncycastle.jce.provider.X509CertificateObject.getPublicKey(Unknown Source) 
    at sun.security.validator.PKIXValidator.initCommon(PKIXValidator.java:92) 
    at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:60) 
    at sun.security.validator.Validator.getInstance(Validator.java:161) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:108) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:204) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) 
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) 
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136) 
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) 
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:637) 
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:89) 

havre de paix I » J'ai tout fait pour configurer SSL sur mon ordinateur, mais les scripts de test JSSE que j'ai lancés semblent indiquer qu'il est installé. Ai-je peut-être sauté une étape nécessaire? L'exception NullPointerException me fait penser que cela pourrait être un bug, plutôt qu'une erreur attendue.

EDIT 15 mai 2012:

J'ai foré vers le bas un peu en utilisant le débogueur Eclipse, au point où je peux voir les certs dans mon SSLSocketFactoryImpl.

SchemeSocketFactory socketfac = httpClient.getConnectionManager().getSchemeRegistry().getScheme("https").getSchemeSocketFactory(); 
socketfac.socketfactory.context.trustManager.trustedCerts.map.table, in debugger. 

Je peux TROUVER le CERT pour le site que j'essaye de frapper; la chose est, en chemin, il y a une exception de pointeur nul dans la table. (Voir images jointes.) Si j'utilise le débogueur pour supprimer les 2 (sur 183) entrées de mon jeu d'entrées qui produisent un NPE, mon code fonctionne parfaitement bien, mais cela ne semble pas être une solution réalisable. Je ne pense pas que ce soit un problème avec mon keystore lui-même - si j'utilise keytool -list -keystore cacerts, il sort 183 entrées, et chacun d'eux semble être formaté de manière appropriée.


Table NPE


Table Good Entry


Table BAD Entry

+1

Attention, vous utilisez une bibliothèque obsolète commons-httpclient. Vous devriez maintenant utiliser les nouvelles bibliothèques HttpComponents http://hc.apache.org/ –

+0

Quelle que soit la raison pour laquelle vous utilisez le fournisseur BouncyCastle pour cela? – Bruno

+0

@Bruno: Je cours le code dans le cadre d'un service Tomcat plus important, et ... c'est ce qu'il a fait par défaut? Comment pourrais-je utiliser un autre fournisseur? –

Répondre

1

Enfin réussi à faire sortir une réponse. J'inclus la version 133 de Bouncycastle en utilisant Maven dans le cadre d'un autre artefact requis par une partie distincte du projet. Ma solution consistait à mettre à jour versionId de bouncycastle à 140 dans mon fichier maven pom.xml.

+0

Je n'avais pas réalisé que vous auriez corrigé votre problème. La version 140 est [encore assez ancienne] (http://bouncy-castle.1462172.n4.nabble.com/Bouncy-Castle-Crypto-Provider-Package-version-1-40-now-available-td1468420.html), Je considérerais une version plus récente. – Bruno

+0

Vous avez raison. J'ai effectué une mise à niveau vers com.bouncycastle 1.46, en fonction de votre réponse ci-dessous. –

0

Le code fonctionne pour moi. Activez le journal de débogage pour voir ce qui se passe.

java.util.logging.Logger.getLogger("org.apache.http.wire").setLevel(java.util.logging.Level.FINEST); 
    java.util.logging.Logger.getLogger("org.apache.http.headers").setLevel(java.util.logging.Level.FINEST); 

    System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); 
    System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); 
    System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); 
    System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug"); 
    System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug"); 
1

Version 133 is about 6 years old. Il y a eu a number of fixes since. La dernière version est 1.47, disponible sous le org.bouncycaste group ID (no longer bouncycastle). Si vous vérifiez les notes de version, un certain nombre de corrections de bogues ont causé NullPointerException s. Je soupçonne également que du code utilise le fournisseur BouncyCastle au lieu du fournisseur Sun alors qu'il n'aurait pas besoin de le faire explicitement ou parce que le fournisseur BC a été inséré avant les fournisseurs Sun/Oracle par défaut en utilisant Security.insertProviderAt(...).

Questions connexes