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.
Attention, vous utilisez une bibliothèque obsolète commons-httpclient. Vous devriez maintenant utiliser les nouvelles bibliothèques HttpComponents http://hc.apache.org/ –
Quelle que soit la raison pour laquelle vous utilisez le fournisseur BouncyCastle pour cela? – Bruno
@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? –