Heute wird es ein bisschen technischer. Vor ein paar Tagen habe ich von den Jungs von safe.me den Auftrag bekommen den Webservice der NV Versicherung in die vorhandenen Vergleichsrechner zu integrieren. Die NV Versicherung liefert ein p12 Zertifikat aus, über das man sich als Client über eine sichere Verbindung authentifiziert. Bei der Anwendung des Zertifikates über SSL bin ich auf einige Probleme gestoßen, für die ich hier mal Lösungen anbieten möchte.
Das PHP5 SoapClient Objekt
Im Grunde genommen ist es mit dem SoapClient Objekt von PHP5 wirklich einfach eine Verbindung mit einem Zertifikat aufzubauen. Beispielhaft könnte das wie folgt aussehen.
$options = [
'local_cert' => dirname(__FILE__) . 'mycert.p12',
'authentication' => SOAP_AUTHENTICATION_DIGEST
];
$client = new SoapClient(
'https://www.mm-newmedia.de/pfad/zur/wsdl/datei.wsdl',
$options
);
Ihr werdet relativ schnell merken, dass es hier eine ziemlich nette Fehlermeldung gibt, wenn ihr den Soap Client versucht mit einem p12 Zertifikat zu initialisieren. Die Fehlermeldung sieht dann in etwa so aus.
SSL read: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure, errno 0
Das sieht ganz schön dramatisch aus, ist es aber eigentlich gar nicht. Diese Fehlermeldung sagt eigentlich nur aus, dass kein Zertifikat gefunden werden kann. Der Pfad ist richtig. Der Dateiname auch. Dazu muss man wissen, dass das PHP5 SoapClient Objekt nicht mit p12 Zertifikaten umgehen kann. Wir benötigen hierfür ein Zertifikat im pem Format.
Von p12 zu pem
Um das Zertifikat vom p12 Format in ein pem Format umwandeln zu können, muss zwingend openSSL auf dem Server oder der lokalen Entwicklungsumgebung installiert sein. Sobald ihr openSSL installiert habt, könnte ihr mit der Umwandlung beginnen. Folgender Beispielcode kann z.B. über die Kommandozeile (cmd) von Windows angewandt werden.
openssl pkcs12 -in mycert.p12 -out mycert.pem -nodes -clcerts
Das Zertifikat wird dann im pem Format im angegebenen Verzeichnis abgelegt.
Wie funktioniert das jetzt mit dem PHP Soap Client?
Im Grunde genommen ändert sich am Aufruf des Clients nicht viel. Ihr gebt lediglich das neu erstellte pem Zertifikat an. Beispielhaft sieht das dann so aus:
$options = [
'local_cert' => dirname(__FILE__) . 'mycert.pem',
'authentication' => SOAP_AUTHENTICATION_DIGEST
];
$client = new SoapClient(
'https://www.mm-newmedia.de/pfad/zur/wsdl/datei.wsdl',
$options
);
Der Soap Request über SSL sollte nun reibungslos funktionieren.
Fazit
Die PHP Dokumentation verliert über dieses Verhalten des SoapClient Objektes im Zusammenhang mit SSL kein einziges Wort. Es hat einiges an Zeit und Nerven gekostet hinter dieses kleine Geheimnis des Soap Clients zu kommen. Halten wir also fest: Der PHP Soap Client kann nicht mit p12 Zertifikaten umgehen und die Umwandlung von p12 in pem ist kinderleicht.
Haben wir also wieder was gelernt. 😉
Rechtschreibfehler: athentication = authentication
Vielen Dank für den Hinweis. Der Rechtschreibfehler wurde korrigiert.