Aplikace v javě, která komunikuje přes https není schopna navázat spojení a vypisuje následující chybu:
06.02.2025 10:11:16.627 *ERROR* [CM Event Dispatcher (Fire ConfigurationEvent: pid=cz.inited.xxx)] cz.inited.xxx [cz.inited.xxx] The activate method has thrown an exception (javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://xxx/eos/webservices/eos_org_structure_read_v2_0_0?wsdl. It failed with:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.)
javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://xxx/eos/webservices/eos_org_structure_read_v2_0_0?wsdl. It failed with:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:250)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:231)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:194)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:163)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:348)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:306)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:215)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:196)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:192)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.<init>(Service.java:77)
Problém je v tom, že certifikát, který se používá pro https vydala certifikační autorita, kterou java svět neuznává. Tím pádem ho považuje za nedůvěryhodný.
Získáme tedy certifikát certifikační autority, provedeme import do seznamu důvěryhodných certifikačních autorit a bude to fungovat.
1. získání certifikátu certifikační autority
Buď certifikát máme nebo požádáme admina serveru nebo si ho vytáhneme pomocí openssl:
$ openssl s_client -connect host.cz:8080
CONNECTED(00000003)
...
...
Server certificate
-----BEGIN CERTIFICATE-----
MIIEVzCCAz+gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCBjTELMAkGA1UEBhMCQ1ox
xxx
xxx
l+vhRicosvxgcNw=
-----END CERTIFICATE-----
subject=/C=CZ/...
issuer=/C=CZ/...
---
No client certificate CA names sent
---
SSL handshake has read 2038 bytes and written 465 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: D4E44A41B85EAD2ABFD117E97B8204B93B7DF7D788280F7FC0A63988853385CAB6EB55E297BBCC20189ECF56248F19EA
Key-Arg : None
Start Time: 1738846289
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
Tento příkaz vypíše všechny certifikáty, které server používá. Může být pouze jeden, ale může jich být více. V případě, že je jen jeden, je dost pravděpodobné, že to není certifikát certifikační autority a bude potřeba požádat admina.
Certifikát je text, který začíná "-----BEGIN CERTIFICATE-----" a končí "-----END CERTIFICATE-----". Toto včetně obsahu mezi tím je třeba vykopírovat a uložit do souboru. Pokud je v odpovědi certifikátů víc, uložit každy certifikát zvlášť do samostatného souboru.
2. Import do javy
Java má seznam důvěryhodných certifikátů ve souboru JAVA_HOME/jre/lib/security/cacerts
Import certifikátu provedeme postupně pro všechny certifikáty takto:
keytool -import -file cert1.pem -alias cert1 -keystore cacerts
Heslo pro import je: changeit
A to je celé.