2

This question has already been asked, but the answer was either to set an allow-all TrustManager, or to import the CA certificate, or there was no answer.

This is my environment:

PC
|
Enterprise Proxy which intercepts HTTPS traffic and uses self-signed certificate
|
Internet

And my test program:

public class Main {

    public static void main (String[] args) throws Exception {
        if (args.length < 1) {
            System.err.println("First argument must be an URL");
            return;
        }
        System.out.println("Testing: " + args[0]); connection = (HttpURLConnection) new URL(args[0]).openConnection();
        System.out.println("Response code: " + connection.getResponseCode());
    }
}

By default, this throws:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

So I used Chrome to go to https://www.google.com, pressed F12 opened Security > View certificate:

Certifcate path

So to my understanding, the enterprise proxy issued the certificate for www.google.ch and therefore needs to be trusted. I therefore display the root certificate (proxywg) and export it to a file called proxywg.cer as Base-64-encoded X.509 (.CER):

Certificate export

Then, I'm going to import it into my JRE's cacerts:

keytool -import -alias proxywg -keystore D:\development\programs\java\jdk1.8.0_112\jre\lib\security\cacerts -file E:\proxywg.cer -storepass changeit

Next test with my program gives me:

java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

So it's a different error now, telling me that I imported the certificate into the correct cacerts file. But why doesn't it work? Launching with -Djavax.net.debug=ssl gives me (I picked what I think are the relevant parts):

adding as trusted cert:
  Subject: CN=proxywg, OU=..., O=..., L=..., ST=..., C=...
  Issuer:  CN=proxywg, OU=..., O=..., L=..., ST=..., C=...
  Algorithm: RSA; Serial number: 0x1
  Valid from Thu Jan 29 10:00:00 CET 2015 until Sat Jan 29 11:00:00 CET 2028

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus: ...
  public exponent: 65537
  Validity: [From: Fri Jul 21 09:12:49 CEST 2017,
               To: Sat Jul 21 09:12:49 CEST 2018]
  Issuer: CN=proxywg, OU=..., O=..., L=..., ST=..., C=...
  SerialNumber: [    b87ea686 bf2723dc b9044d34 b2ae1a28 a4c187bb]

Certificate Extensions: 6
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
[CN=proxywg, OU=..., O=..., L=..., ST=..., C=...]
SerialNumber: [    00]
]

[2]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[3]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[4]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[5]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: www.google.com
]

[6]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 33 3A FE FD 3E 79 7A 67   2E 44 0F F1 DB DF EC FB  3:..>yzg.D......
0010: FB C4 7E 08                                        ....
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 3D 91 E5 EC B5 94 66 07   47 EC BC 74 48 C9 A1 8E  =.....f.G..tH...
0010: 34 EB AE 8D 71 F1 9A F6   AE 6E 69 B8 77 FF 71 60  4...q....ni.w.q`
0020: 8B 97 73 25 14 72 8A FA   21 A7 77 C7 74 28 77 FA  ..s%.r..!.w.t(w.
0030: C4 9A 96 B5 ED DA 96 4B   09 20 E7 A8 8D 6E 9A 1A  .......K. ...n..
0040: 37 A6 2B AB A3 AE 9F 94   59 10 95 4C 0A 7B BB D8  7.+.....Y..L....
0050: 49 6D 72 1D B2 DA CD 97   4E 4F 28 22 24 7B 71 D5  Imr.....NO("$.q.
0060: 3E B7 92 6E D2 18 9B 29   4D 30 13 87 13 FE E3 15  >..n...)M0......
0070: D9 7F 25 33 D0 57 A3 AD   93 66 43 50 0B 95 F4 6B  ..%3.W...fCP...k
0080: FB 54 0C 43 A9 76 05 1E   04 48 71 70 BA 38 29 EA  .T.C.v...Hqp.8).
0090: D7 AF 46 09 18 FA DC D0   3A D1 3E C4 66 E2 DA 4F  ..F.....:.>.f..O
00A0: 9B 52 DA 2C 17 06 A2 68   AD DE B9 E7 F3 15 6E 17  .R.,...h......n.
00B0: F4 C8 CE 94 EB 16 4C 18   A0 35 0C DE 62 6F 43 99  ......L..5..boC.
00C0: 53 B8 B6 23 9C 31 69 81   DC 20 91 1D A4 CE D0 8D  S..#.1i.. ......
00D0: BA 85 B5 02 D4 B7 CA AE   58 C4 BB 8D 7B BA 52 9F  ........X.....R.
00E0: 4E 35 59 ED 23 7A 35 02   61 C7 49 F6 2C 0F 4F A0  N5Y.#z5.a.I.,.O.
00F0: C3 26 9A D3 79 5B A4 25   86 5A 25 44 88 B2 C0 01  .&..y[.%.Z%D....

]
***
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
main, SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown
main, WRITE: TLSv1.2 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

How come the certificate path "does not chain with any of the trust anchors"? Am I missing something?

In the end, I'm trying to get Gradle being able to access the internet.

Michel Jung
  • 2,966
  • 6
  • 31
  • 51
  • Probably `proxywg` is generating the certificate for `google.ch` on the fly and is different when you point the JVM that the recovered from browser. Try to import in cacerts the root certificate of `proxywg`, not the final certificate. This means you trust the proxy – pedrofb Jul 21 '17 at 07:53
  • Yes, that's what the proxy does. To my understanding, `proxywg` has no root certificate but **is** the root certificate, which is also the one I imported (see: "I therefore display the root certificate (proxywg) and export it to a file called `proxywg.cer`). Which is why I expected it to be the "trust anchor". – Michel Jung Jul 21 '17 at 08:13
  • Reading too fast, I thought you imported the final certificate. May be a missing intermediate not shown by browser? – pedrofb Jul 21 '17 at 08:26
  • Read [this](https://stackoverflow.com/questions/11153058/java7-refusing-to-trust-certificate-in-trust-store). Has the CA certificate of `proxywg` the appropriate keyUsage? It should contain `certSign` and basicConstraints{ CA = true – pedrofb Jul 21 '17 at 13:01

1 Answers1

1

I followed your post to overcome the precisely same issue; Java does not like the self-signed certificate that our enterprise proxy issues to internet sites that I access.

I did nearly everything as same as you do, except for one thing. I specify the -trustcacerts option to the keytool command, in addition to all other parameters that you too specify.

Hope it helps.

  • This has no longer been relevant to me, but your solution sounds correct :) Without testing, I'll accept this answer. Maybe someone can confirm. – Michel Jung Nov 12 '19 at 14:50