- handshake failed
- HTTP 403, Permission Denied.
HTTPS a WS-Security
S čím jsem ale dosud neměl zkušenost, je WS-Security; ještě dopoledne jsem si myslel, že šifrování SOAP komunikace je prostě dílo HTTPS. Během dne jsem pomalu začínal chápat, že jsem vedle jak ta jedle.Zatímco HTTPS (HTTP over TLS/SSL) šifruje veškerou komunikaci, WS-Security používá obyčejné HTTP (nebo i HTTPS) a šifruje se jen payload (tj. data v SOAP) - pro představu, uvidíte něco takového (namespaces jsem umazal a trochu to naformátoval):
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<wsse:Security>
<xenc:ReferenceList>
<xenc:DataReference URI="#ED-1"/>
</xenc:ReferenceList>
</wsse:Security>
</S:Header>
<S:Body>
<xenc:EncryptedData Id="ED-1" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<ds:KeyInfo>
<wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
<wsse:Reference URI="#null"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>[zašifrovaná data v Base64]</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</S:Body>
</S:Envelope>
SoapUI
Návodem se zdržovat nebudu, najdete jich na internetu hromadu.Nastavení SoapUI ani jeho dokumentace navíc vůbec nepočítá s lidskou naivitou, a tak velká část blogů a fór radí neúplné nesmysly na podobně neúplné otázky. Člověk pak ze zoufalství všude nastavuje keystore, všude nastavuje klíče, certifikáty, prostě klasický shotgun debugging, který ale k cíli nevede.
SoapUI mi tedy rozhodně s řešením nepomohlo, neb navíc vytrvale odmítalo vzít na vědomí nastavení -Djavax.net.debug=all a v logu nebylo stále nic než jen tříslovné chybové hlášení.
Jen aby bylo jasno - k nastavení HTTPS stačí jen otevřít globální nastavení SoapUI, tj. File - Preferences - SSL Settings, nastavit keystore a jeho heslo - hotovo. Nezapomeňte nastavení uložit, což má SoapUI taky celkem nepřirozeně jako další položku menu.
Všechna ostatní nastavení v projektu (Outgoing/Incoming keystore, Encryption, atd.) se týkají WS-Security a pokud vám jde jen o HTTPS, můžete je ignorovat.
OpenSSL
Po šesti hodinách střílení z brokovnice jste rádi, že jste se nezastřelili sami. Přišel čas zapnout mozek. Dobrá, zkusíme to přes OpenSSL, blbé SoapUI!Vyexportujete si klíče i všechny certifikáty z JKS do PEM souborů. Spustíte OpenSSL a postupně mu nasázíte všechny argumenty - klíč, klientský certifikát, důvěryhodné certifikáty. Vypnete ověření hostname i serverového certifikátu, pro všechny případy. A - ono to funguje! Blbé SoapUI!!! No počkat, ale něco tu nehraje ...
Meanwhile ...
Moje panika nakazila i místní. Někteří také stříleli z brokovnic, někteří ale zavětřili, že tu opravdu něco nehraje. Všechno jsem dělal dobře (jeden znal i SoapUI, byť také úplně nerozuměl kouzlům WS-Security, ale věděl, že to mám všechno vyházet. Nepomohlo to, ale budiž.Mezitím mi ale server začal odpovídat jinak, namísto věčného HTTP 403 - tentokrát na žádné HTTP nedošlo a přišlo rovnou "Handshake failed: Bad certificate."
Asi hodinu mi trvalo, než mi došlo, že server mluví o mém certifikátu, který mi místní autorita s pomocí Windows bezmyšlenkovitě podepsala a já si bláhově myslel, že když to funguje přes OpenSSL, musí být problém v nastavení SoapUI.
Pointa
Když moje největší posila (toho člověka jsem začal mít rád, neb mě citelně táhl správným směrem) už asi počtvrté přišla - a kdesi mezi jejími větami jsem zachytil slovo "Extension" ... svitlo mi. Jen jsem nevěděl, jak se vlastně Extensions k certifikátům přidávají ... to už teď taky vím: dokumentace keytoolKdybyste náhodou zařizovali klíč a klientský certifikát pro SSL (HTTPS) a divili se, proč to pořád končí handshake failed, zatímco přes OpenSSL, kterému dáte privátní klíč (PEM), klientský certifikát (PEM) a ca-certs (další PEM), to chodí ... Váš klientský certifikát postrádá Extensions, čili schválená použití certifikátu, který pak tím pádem není možno použít pro šifrování ani autentizaci.
Extensions k certifikátu generujete s žádostí o podpis, příp. je tam může přihodit i podepisující, soudě podle dokumentace. Např. šifrování, dešifrování, podpis ... Každá Extension má své vlastní OID, ostatně viz parametr -ext v dokumentaci keytool a např. MSDN: Certificate Extensions
Závěrem budiž konstatováno, že SoapUI blbé není.
Zamyšlení
Shodou okolností řeším problém s HTTPS - stařičký CISCO loadbalancer mu totiž nerozumí, tudíž nemůže balancovat. Jen mě tak napadlo, že s použitím WS-Security se nějaké HTTPS vůbec nemusí řešit.Jenže - u HTTPS je komplikací i samotné sledování komunikace, tj. řekl bych, že je co se týče bezpečnosti o řád jinde.
Na druhou stranu, každá proxy potřebuje požadavek rozšifrovat, než ho pošle dál. To by u HTTP a WS-Security nemusela.
A zase ... když bude proxy s loadbalancerem v cestě jediná, resp. do cesty se strčí Apache, který komunikaci na vstupu do uzavřené části zbaví šifrování, nač řešit WS-Security. Tu bych řešil v případě nějaké ohromné infrastruktury, do které přistupuje kde kdo ...
Nebo se pletu?