Kort svar
Browseren og dine runtimes bruger forskellige trust stores. Browseren stoler typisk på operativsystemets store (eller sin egen) og er eftergivende med manglende intermediates. Java bruger sin egen cacerts, og .NET bruger Windows-certifikatlageret (eller på Linux OpenSSL's store). Hvis serveren mangler en intermediate, eller den nødvendige root ikke er i runtime'ens store, fejler kun runtime'en — ikke browseren.
De to mulige årsager
- Manglende intermediate på serveren. Browsere cacher intermediates og kan hente dem via AIA; Java og .NET gør det ofte ikke. Resultatet er
unable to get local issuer certificateellerPKIX path building failedi Java, mens browseren er tilfreds. Dette er den hyppigste årsag — og det er en server-fejl, ikke en klient-fejl. - Manglende root i runtime'ens trust store. En ny eller intern CA's root er ikke i Java's
cacertseller Windows-lageret. Her skal root'en importeres i den rigtige store.
Find ud af hvilken det er
Tjek først om serveren sender hele kæden (uafhængigt af klient):
openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null \ | grep -c "BEGIN CERTIFICATE"
Får du 1, mangler intermediate'en på serveren — ret det dér, så virker både Java, .NET og curl. Får du 2+, er kæden fin, og problemet er trust store'en i din runtime.
Java: cacerts og PKIX
Den klassiske Java-fejl er sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path. Se hvad der allerede er i din truststore, og importér en manglende root:
# Liste roots i den aktive JVM keytool -list -keystore "$JAVA_HOME/lib/security/cacerts" -storepass changeit # Importér en intern/manglende root keytool -importcert -alias corp-root -file corporate-root.crt \ -keystore "$JAVA_HOME/lib/security/cacerts" -storepass changeit
Bemærk forskellen på en keystore (din egen identitet/private nøgle) og en truststore (de CA'er du stoler på). Det er truststore'en der er relevant her.
.NET
På Windows bruger .NET maskinens certifikatlager — importér root'en under "Trusted Root Certification Authorities" (eller for den aktuelle bruger). På Linux bruger .NET OpenSSL's CA-bundle, så update-ca-certificates efter at have lagt root'en i /usr/local/share/ca-certificates/ løser det. Tjek også at private-key-rettighederne er korrekte, hvis det er et klientcertifikat.
Den vigtigste pointe
Fordi browseren skjuler manglende intermediates, slipper fejlen ofte forbi QA og rammer først en server-til-server-integration. CertControl tester hele kæden udefra — som en streng klient, ikke en eftergivende browser — og markerer servere der kun sender et delvist chain. Så fanger I problemet før jeres Java- eller .NET-integrationer gør. Det er én af de hyppige TLS handshake-fejl, og forståelsen af certifikat-kæden er det der gør fixet oplagt.
Ofte stillede spørgsmål
Hvorfor er browseren mere tilgivende end Java?
Browsere cacher intermediates fra tidligere besøg og kan hente manglende intermediates via certifikatets AIA-felt. Java og .NET gør typisk ingen af delene og kræver at serveren selv sender hele kæden.
Hvad er forskellen på keystore og truststore?
En keystore indeholder din egen identitet — privat nøgle og certifikat. En truststore indeholder de CA-rootcertifikater du stoler på. Ved valideringsfejl er det næsten altid truststore'en der mangler noget.
Skal jeg redigere systemets cacerts?
Helst ikke direkte. Brug en separat truststore via -Djavax.net.ssl.trustStore, eller importér i en kopi. At ændre den globale cacerts kan blive overskrevet ved næste JDK-opdatering.
PKIX path building failed — hvad betyder det?
Det er Java's udgave af "kunne ikke bygge en gyldig kæde til en betroet root". Næsten altid en manglende intermediate på serveren eller en manglende root i din truststore.