# HTTPS mit Apache HttpClient



## Q-Base (24. Nov 2008)

Hallo, 

zwar habe ich den SSL Guide (http://hc.apache.org/httpclient-3.x/sslguide.html) durch, aber trotzdem bekomme ich keine Verbindung per HTTPS. Meine Verbindungen per HTTP funktionieren. Egal wie ich die Verbindung etablieren will, quittiert mir die API mit einer Exception ...

```
[...] PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: \
unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
	at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
	at java.io.BufferedOutputStream.flush(Unknown Source)
	at java.io.FilterOutputStream.flush(Unknown Source)
	at org.apache.commons.httpclient.methods.StringRequestEntity.writeRequest(StringRequestEntity.java:146)
	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
	at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
```

Debuggen hilft auch nicht viel, denn genau der Teil ist in einer Bibliothek ohne Sourcen. 

Auf dem Server läuft natürlich ein selbst signiertes Zertifikat, dass nur zum Verschlüsseln gedacht ist. Aber es sollte doch trotzdem funktionieren (?!) .

Im Internet finde ich in Foren auch Klassen wie  AuthSSLProtocolSocketFactory und EasySSLProtocolSocketFactory, die im 'contrib'-Package liegen sollen. Dieses Package gibt es aber bei meiner Version 3.1 von HttpClient gar nicht. Liegt es vielleicht daran? 

Ciao, Q


----------



## Q-Base (24. Nov 2008)

Hallo, 

also ich habe nun mit einigen Zeilen Code aus dem Internet probiert. Also wenn ich SSLSockets selbst erzeuge und einen TrustManager implementiere, dann kann ich auch selbst signierte Zertifikate speichern und akzeptieren. Aber im Prinzip bringt mich das ja gar nicht weiter, denn ich müsste ja HttpClient dazu bekommen, das Zertifikat zu akzeptieren. Selbst wenn ich es ist einem KeyStore speichern könnte, müsste ich ja auch als vertrauchenswürdig laden können. 

Und das kann ich nicht. 
Hat das schonmal jemand gemacht? 

Ciao, Q


Qullen aus dem Internet: 
http://blogs.sun.com/andreas/entry/no_more_unable_to_find 
http://blogs.sun.com/andreas/resource/InstallCert.java
EasySSLProtocolSocketFactory.java


----------



## FArt (24. Nov 2008)

Wie es aussieht, kann der Pfad zu einer "trusted authority" nicht aufgelöst werden. Vermutlich hast du das selbstgebaute Zertifikat im Client-Keystore nicht importiert oder der entsprechende Keystore wird nicht verwendet.

Mit Sicherheit weicht deine Implementierung von den Beispielen ab, denn die funktionieren alle.
Vergleiche noch mal genau und nimm die passende Version der API.

Das hier kann auch helfen: http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/ReadDebug.html


----------



## Q-Base (24. Nov 2008)

Hallo FArt, 

also das Beispiel selbst kann ich auch benutzen, wenn es ein 'richtiges' Zertifikat ist. https://www.verisgn.com ist kein Problem. Sobald ich meinen Host auch nur mit dem einfachsten Get anfrage, bekomme ich diese lange Fehlermeldung. Du wirst also sicher Recht haben, dass ich die "trusted authority" nicht korrekt mache. Ich habe nur noch kein Beispiel gefunden, in dem ich bei HttpClient einen KeyStore verwenden kann. 

Ich schaue mir deinen Link später an. Wünsche einen schönen Abend. 

Ciao, Q


----------



## FArt (25. Nov 2008)

Das könnte daran liegen, dass der Default-Keystore verwendet wird und dort Verisign als trusted authority eingetragen ist.

Ein selbst gemachtes Zertifikat musst du beim Server und Client in den Keystore importieren und diesen dann verwenden.

Begriffe für Google:
java custom keystore
java tutorial keystore
java tutorial ssl


----------

