289

I have a Java client trying to access a server with a self-signed certificate.

When I try to Post to the server, I get the following error:

unable to find valid certification path to requested target

Having done some research on the issue, I then did the following.

  1. Saved my servers domain name as a root.cer file.

  2. In my Glassfish server's JRE, I ran this:

    keytool -import -alias example -keystore cacerts -file root.cer
    
  3. To check the cert was added to my cacert successfully, I did this:

    keytool -list -v -keystore cacerts
    

    I can see the cert is present.

  4. I then restarted Glassfish and retried the 'post'.

I am still getting the same error.

I have a feeling this is because my Glassfish is not actually reading the cacert file that I have amended but maybe some other one.

Have any of you had this issue and can push me in the right direction?

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
TheCoder
  • 8,413
  • 15
  • 42
  • 54
  • 2
    Just to clarify "I have a Java client trying to access a server with a self-signed certificate.": you're talking of using client-certificates that are self-signed, aren't you? Is there any specific configuration for your connector settings on Glassfish (trust store settings, in particular)? – Bruno Feb 09 '12 at 12:25
  • "I have a Java client trying to access a server with a self-signed certificate.": you're talking of using client-certificates that are self-signed, aren't you? - yes. – TheCoder Feb 09 '12 at 13:51
  • 1
    I have found 2 settings in Glassfish JVM: -Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/keystore.jks and -Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/cacerts.jks. I now need to add by cert to one of those. Can you confirm it's the keystore I add it to? – TheCoder Feb 09 '12 at 13:52
  • 8
    On the server, the keystore is for the server cert and its private key (keystore is for what "belongs" to local party). The truststore is for the certs used to verify trust in the remote party. You should add the client cert to your server trust store. (See [this](http://stackoverflow.com/a/4133092/372643) too, although Glassfish doesn't seem to be using the JRE's default location.) – Bruno Feb 09 '12 at 13:56
  • That worked Bruno. I added it to my Glassfish truststore. Thanks so much for you help. You too Dirk. – TheCoder Feb 09 '12 at 14:04
  • This answer may also help: http://stackoverflow.com/questions/4663147/is-there-a-java-setting-for-disabling-certificate-validation – yegor256 Dec 16 '14 at 11:26
  • possible duplicate of [PKIX path building failed: unable to find valid certification path to requested target](http://stackoverflow.com/questions/4062307/pkix-path-building-failed-unable-to-find-valid-certification-path-to-requested) – Nathan Dec 18 '14 at 16:54
  • For Glassfish V4, the process worked for me but like TheCoder, I added to my Glassfish cacerts.jks, not the Java one. – ben_979 Dec 13 '15 at 17:09
  • Check this link [pkix path building failed](http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html) which solved my issue – Ajeesh Jun 08 '16 at 11:24
  • Check your internet. Gradle might want to download some stuff. – Joanne May 23 '18 at 07:49
  • 2
    You can blindly accept all SLL certificates as shown in this full runnable example code - **That's of course insecure!**: http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/ – Dreamspace President Jun 19 '18 at 13:14

17 Answers17

216

Unfortunately - it could be many things - and lots of app servers and other java 'wrappers' are prone to play with properties and their 'own' take on keychains and what not. So it may be looking at something totally different.

Short of truss-ing - I'd try:

java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore ...

to see if that helps. Instead of 'all' one can also set it to 'ssl', key manager and trust manager - which may help in your case. Setting it to 'help' will list something like below on most platforms.

Regardless - do make sure you fully understand the difference between the keystore (in which you have the private key and cert you prove your own identity with) and the trust store (which determines who you trust) - and the fact that your own identity also has a 'chain' of trust to the root - which is separate from any chain to a root you need to figure out 'who' you trust.

all            turn on all debugging
ssl            turn on ssl debugging

The   following can be used with ssl:
    record       enable per-record tracing
    handshake    print each handshake message
    keygen       print key generation data
    session      print session activity
    defaultctx   print default SSL initialization
    sslctx       print SSLContext tracing
    sessioncache print session cache tracing
    keymanager   print key manager tracing
    trustmanager print trust manager tracing
    pluggability print pluggability tracing

    handshake debugging can be widened with:
    data         hex dump of each handshake message
    verbose      verbose handshake message printing

    record debugging can be widened with:
    plaintext    hex dump of record plaintext
    packet       print raw SSL/TLS packets

Source: # See http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#Debug

yegor256
  • 102,010
  • 123
  • 446
  • 597
Dirk-Willem van Gulik
  • 7,566
  • 2
  • 35
  • 40
  • 9
    Thanks a lot! -Djavax.net.ssl.trustStore=/location_of/trustStore solved my problem and the debug info was really helpful too. – RHE Jul 19 '16 at 23:30
  • 8
    java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore ... gives the below error: Error: Could not find or load main class ... – rohith Apr 09 '19 at 10:12
  • 2
    Of course you may also need to specify the truststore's password with -Djavax.net.ssl.trustStorePassword=changeit – user1754036 Feb 06 '20 at 22:52
  • @rohith instead of `...` give it the path to a simple `helloWorld.java`. – vesperto Feb 21 '23 at 13:07
34

Here is the solution , follow the below link Step by Step :

http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/

JAVA FILE : which is missing from the blog

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */



import java.io.*;
import java.net.URL;

import java.security.*;
import java.security.cert.*;

import javax.net.ssl.*;

public class InstallCert {

    public static void main(String[] args) throws Exception {
    String host;
    int port;
    char[] passphrase;
    if ((args.length == 1) || (args.length == 2)) {
        String[] c = args[0].split(":");
        host = c[0];
        port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
        String p = (args.length == 1) ? "changeit" : args[1];
        passphrase = p.toCharArray();
    } else {
        System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
        return;
    }

    File file = new File("jssecacerts");
    if (file.isFile() == false) {
        char SEP = File.separatorChar;
        File dir = new File(System.getProperty("java.home") + SEP
            + "lib" + SEP + "security");
        file = new File(dir, "jssecacerts");
        if (file.isFile() == false) {
        file = new File(dir, "cacerts");
        }
    }
    System.out.println("Loading KeyStore " + file + "...");
    InputStream in = new FileInputStream(file);
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(in, passphrase);
    in.close();

    SSLContext context = SSLContext.getInstance("TLS");
    TrustManagerFactory tmf =
        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
    SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
    context.init(null, new TrustManager[] {tm}, null);
    SSLSocketFactory factory = context.getSocketFactory();

    System.out.println("Opening connection to " + host + ":" + port + "...");
    SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
    socket.setSoTimeout(10000);
    try {
        System.out.println("Starting SSL handshake...");
        socket.startHandshake();
        socket.close();
        System.out.println();
        System.out.println("No errors, certificate is already trusted");
    } catch (SSLException e) {
        System.out.println();
        e.printStackTrace(System.out);
    }

    X509Certificate[] chain = tm.chain;
    if (chain == null) {
        System.out.println("Could not obtain server certificate chain");
        return;
    }

    BufferedReader reader =
        new BufferedReader(new InputStreamReader(System.in));

    System.out.println();
    System.out.println("Server sent " + chain.length + " certificate(s):");
    System.out.println();
    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        System.out.println
            (" " + (i + 1) + " Subject " + cert.getSubjectDN());
        System.out.println("   Issuer  " + cert.getIssuerDN());
        sha1.update(cert.getEncoded());
        System.out.println("   sha1    " + toHexString(sha1.digest()));
        md5.update(cert.getEncoded());
        System.out.println("   md5     " + toHexString(md5.digest()));
        System.out.println();
    }

    System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
    String line = reader.readLine().trim();
    int k;
    try {
        k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
    } catch (NumberFormatException e) {
        System.out.println("KeyStore not changed");
        return;
    }

    X509Certificate cert = chain[k];
    String alias = host + "-" + (k + 1);
    ks.setCertificateEntry(alias, cert);

    OutputStream out = new FileOutputStream("jssecacerts");
    ks.store(out, passphrase);
    out.close();

    System.out.println();
    System.out.println(cert);
    System.out.println();
    System.out.println
        ("Added certificate to keystore 'jssecacerts' using alias '"
        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

    private final X509TrustManager tm;
    private X509Certificate[] chain;

    SavingTrustManager(X509TrustManager tm) {
        this.tm = tm;
    }

    public X509Certificate[] getAcceptedIssuers() {
        throw new UnsupportedOperationException();
    }

    public void checkClientTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        throw new UnsupportedOperationException();
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        this.chain = chain;
        tm.checkServerTrusted(chain, authType);
    }
    }

}
osoclever
  • 373
  • 7
  • 16
user6258309
  • 389
  • 3
  • 2
  • 4
    This solution worked for me, but it needs a small change in the private class SavingTrustManager: `public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0];}` – Richard Jul 04 '16 at 20:29
  • 1
    @Richard,@Paul,@user6258309 I got the error Exception in thread "main" java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(Unknown Source) How I can I fix this – Renjith Krishnan Feb 27 '17 at 05:50
  • 14
    This 'so;lution' is radically insecure. Do not use. – user207421 Dec 06 '18 at 10:26
  • 48
    This answer is mostly code. It doesn't explain why or why not it works. –  Dec 16 '18 at 11:01
17

You need to configuring JSSE System Properties, specifically point to client certificate store.

Via command line:

java -Djavax.net.ssl.trustStore=truststores/client.ts com.progress.Client

or via Java code:

import java.util.Properties;
    ...
    Properties systemProps = System.getProperties();
    systemProps.put("javax.net.ssl.keyStorePassword","passwordForKeystore");
    systemProps.put("javax.net.ssl.keyStore","pathToKeystore.ks");
    systemProps.put("javax.net.ssl.trustStore", "pathToTruststore.ts");
    systemProps.put("javax.net.ssl.trustStorePassword","passwordForTrustStore");
    System.setProperties(systemProps);
    ...

For more refer to details on RedHat site.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Vic
  • 1,985
  • 1
  • 19
  • 30
  • Had the same problem with Spring Boot, Spring Cloud microservices, and a self-signed SSL certificate. I was able to set keyStore and keyStorePassword in application.properties and get it to work like that out of the box, but was unsuccessuful to do the same with trustStore and trustStorePassword. This answer worked for me for trust store. – Mate Šimović Jun 30 '17 at 14:42
  • Java code worked for me. Thank you. – ammy Sep 14 '22 at 09:47
15

(repost from my other response)
Use cli utility keytool from java software distribution for import (and trust!) needed certificates

Sample:

  1. From cli change dir to jre\bin

  2. Check keystore (file found in jre\bin directory)
    keytool -list -keystore ..\lib\security\cacerts
    Password is changeit

  3. Download and save all certificates in chain from needed server.

  4. Add certificates (before need to remove "read-only" attribute on file ..\lib\security\cacerts), run:

    keytool -alias REPLACE_TO_ANY_UNIQ_NAME -import -keystore.\lib\security\cacerts -file "r:\root.crt"

accidentally I found such a simple tip. Other solutions require the use of InstallCert.Java and JDK

source: http://www.java-samples.com/showtutorial.php?tutorialid=210

Madbreaks
  • 19,094
  • 7
  • 58
  • 72
  • great, thanks! with the help of `keytool -alias REPLACE_TO_ANY_UNIQ_NAME -import -keystore.\lib\security\cacerts -file "r:\root.crt"`, i don't need to change my java code `CloseableHttpClient httpClient = HttpClients.createDefault();` – frank Jan 18 '21 at 06:50
9

I came across this error while trying to access a https url from my application which was using self-signed certificate. What they provide is a .cert file and I was not sure where to put that. I solved it the following way:

keytool location is under JDK/bin folder

Method 1: Add the certificate to default Java Truststore - cacerts:

keytool -import -alias myCert -file C://certificate.cert -keystore C://Program Files//Java//jdk1.8.0_271//jre//lib//security//cacerts

Password: changeit

Method 2:

Create a Trust Store:

keytool -import -alias myCert -file C://certificate.cert -keystore myTrustStore

It gives you the following prompts, which can be filled up as:

Enter keystore password:changeit
Re-enter new password:changeit
Trust this certificate?yes

This will create a myTrustStore file inside a folder where you ran this command. Copy this "mytrustStore" to a convenient location.

Use the Trust Store:

While you are running your application/server pass these JVM arguments:

-Djavax.net.ssl.trustStore=C://myTrustStore -Djavax.net.ssl.trustStorePassword=changeit
Deb
  • 5,163
  • 7
  • 30
  • 45
7

I had the same problem with sbt.
It tried to fetch dependencies from repo1.maven.org over ssl
but said it was "unable to find valid certification path to requested target url".
so I followed this post and still failed to verify a connection.
So I read about it and found that the root cert is not enough, as was suggested by the post,so -
the thing that worked for me was importing the intermediate CA certificates into the keystore.
I actually added all the certificates in the chain and it worked like a charm.

Danny Mor
  • 1,143
  • 12
  • 12
  • Experienced the same: only importing root does not work. When importing the intermediate one, it does. What might be the reason for this? – Vankog Oct 01 '20 at 06:22
  • You only need one of the signer certificates, not all of them. – user207421 Aug 01 '22 at 23:56
5

Solution when migrating from JDK 8 to JDK 10

JDK 10

root@c339504909345:/opt/jdk-minimal/jre/lib/security #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 80 entries

JDK 8

root@c39596768075:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 151 entries

Steps to fix

  • I deleted the JDK 10 cert and replaced it with the JDK 8
  • Since I'm building Docker Images, I could quickly do that using Multi-stage builds
    • I'm building a minimal JRE using jlink as /opt/jdk/bin/jlink \ --module-path /opt/jdk/jmods...

So, here's the different paths and the sequence of the commands...

# Java 8
COPY --from=marcellodesales-springboot-builder-jdk8 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts /etc/ssl/certs/java/cacerts

# Java 10
RUN rm -f /opt/jdk-minimal/jre/lib/security/cacerts
RUN ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts
Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
4

I am working on a tutorial for REST web services at www.udemy.com (REST Java Web Services). The example in the tutorial said that in order to have SSL, we must have a folder called "trust_store" in my eclipse "client" project that should contain a "key store" file (we had a "client" project to call the service, and "service" project that contained the REST web service - 2 projects in the same eclipse workspace, one the client, the other the service). To keep things simple, they said to copy "keystore.jks" from the glassfish app server (glassfish\domains\domain1\config\keystore.jks) we are using and put it into this "trust_store" folder that they had me make in the client project. That seems to make sense: the self-signed certs in the server's key_store would correspond to the certs in the client trust_store. Now, doing this, I was getting the error that the original post mentions. I have googled this and read that the error is due to the "keystore.jks" file on the client not containing a trusted/signed certificate, that the certificate it finds is self-signed.

To keep things clear, let me say that as I understand it, the "keystore.jks" contains self-signed certs, and the "cacerts.jks" file contains CA certs (signed by the CA). The "keystore.jks" is the "keystore" and the "cacerts.jks" is the "trust store". As "Bruno", a commenter, says above, "keystore.jks" is local, and "cacerts.jks" is for remote clients.

So, I said to myself, hey, glassfish also has the "cacerts.jks" file, which is glassfish's trust_store file. cacerts.jsk is supposed to contain CA certificates. And apparently I need my trust_store folder to contain a key store file that has at least one CA certificate. So, I tried putting the "cacerts.jks" file in the "trust_store" folder I had made, on my client project, and changing the VM properties to point to "cacerts.jks" instead of "keystore.jks". That got rid of the error. I guess all it needed was a CA cert to work.

This may not be ideal for production, or even for development beyond just getting something to work. For instance you could probably use "keytool" command to add CA certs to the "keystore.jks" file in the client. But anyway hopefully this at least narrows down the possible scenarios that could be going on here to cause the error.

ALSO: my approach seemed to be useful for the client (server cert added to client trust_store), it looks like the comments above to resolve the original post are useful for the server (client cert added to server trust_store). Cheers.

Eclipse project setup:

  • MyClientProject
  • src
  • test
  • JRE System Library
  • ...
  • trust_store
    ---cacerts.jks ---keystore.jks

Snippet from MyClientProject.java file:

static {
  // Setup the trustStore location and password
  System.setProperty("javax.net.ssl.trustStore","trust_store/cacerts.jks");
  // comment out below line
  System.setProperty("javax.net.ssl.trustStore","trust_store/keystore.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
  //System.setProperty("javax.net.debug", "all");

  // for localhost testing only
  javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
        public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
          return hostname.equals("localhost");
        }

  });
}
Steve T
  • 165
  • 11
3

Wasted a lot of time on that issue. If you imported the certificate and you can see it listed here.

keytool -list -v -keystore $JAVA_HOME/lib/security/cacerts

Then create the new one, with the following command, replace SITE_NAME, SITE_PORT, CERTIFICATE_NAME and path to save file.

echo -n | openssl s_client -connect SITE_NAME:SITE_PORT  \
| openssl x509 > /path/to/save/CERTIFICATE_NAME.cert

In my case, I experienced problem using Keycloak with Spring. After I created certificate with this command and imported to keystore, the problem was solved and it works fine

leonaugust
  • 186
  • 1
  • 4
  • 15
2

My problem was that a Cloud Access Security Broker, NetSkope, was installed on my work laptop through a software update. This was altering the certificate chain and I was still not able to connect to the server through my java client after importing the entire chain to my cacerts keystore. I disabled NetSkope and was able to successfully connect.

gary69
  • 3,620
  • 6
  • 36
  • 50
1

Check if the file $JAVA_HOME/lib/security/cacerts exists! In my case it was not a file but a link to /etc/ssl/certs/java/cacerts and also this was a link to itself (WHAT???) so due to it JVM can't find the file.

Solution: Copy the real cacerts file (you can do it from another JDK) to /etc/ssl/certs/java/ directory and it'll solve your problem :)

0x7E1
  • 41
  • 1
  • 5
  • indeed JDK maintains a link and maybe for compatibility with older APIs, SDKs... I successfully managed to do the same... I'm moving from JDK 8 to JDK 10 and using Docker so I just needed to copy the cacerts from an image to another... I created the link and same exact way ... `rm -f /opt/jdk-minimal/jre/lib/security/cacerts ; ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts` – Marcello DeSales Nov 11 '18 at 07:43
1

note for eclipse / Sts users:

Because eclipse uses its own JRE, you should add certs to its own JRE keystore. I had this issue until I added certs to Sts's JRE.

SSL log:

`javax.net.ssl|DEBUG|1A|restartedMain|2021-12-06 23:04:00.874` IRST|TrustStoreManager.java:113|trustStore is: D:\sts-4.12.0.RELEASE\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_16.0.2.v20210721-1149\jre\lib\security\cacerts
This is the full path: "sts-4.12.0.RELEASE\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_16.0.2.v20210721-1149\jre\lib\security\cacerts"
David Brossard
  • 13,584
  • 6
  • 55
  • 88
hamidreza75
  • 567
  • 6
  • 15
0

In my case I was facing the problem because in my tomcat process specific keystore was given using

-Djavax.net.ssl.trustStore=/pathtosomeselfsignedstore/truststore.jks

Wheras I was importing the certificate to the cacert of JRE/lib/security and the changes were not reflecting. Then I did below command where /tmp/cert1.test contains the certificate of the target server

keytool -import -trustcacerts -keystore /pathtosomeselfsignedstore/truststore.jks -storepass password123 -noprompt -alias rapidssl-myserver -file /tmp/cert1.test

We can double check if the certificate import is successful

keytool -list -v -keystore /pathtosomeselfsignedstore/truststore.jks

and see if your taget server is found against alias rapidssl-myserver

Sanjay Bharwani
  • 3,317
  • 34
  • 31
0

In my case, I was getting error connecting to AWS Gov Postgres RDS. There is a separate link for GOV RDS CA certs- https://s3.us-gov-west-1.amazonaws.com/rds-downloads/rds-combined-ca-us-gov-bundle.pem

Add this pem certs to cacerts of java. You can use below script.

------WINDOWDS STEPS-------

  1. Use VSCODE editor and install openssl, keytool plugins
  2. create a dir in C:/rds-ca
  3. place 'cacerts' file and below script file - 'addCerts.sh' inside dir 'rd-ca'
  4. run from vscode: 4.1 cd /c/rds-ca/ 4.2 ./addCerts.sh
  5. Copy cacerts to ${JAVA_HOME}/jre/lib/security

Script code:

#!/usr/bin/env sh

OLDDIR="$PWD"

CACERTS_FILE=cacerts

cd /c/rds-ca

echo "Downloading RDS certificates..."

curl  https://s3.us-gov-west-1.amazonaws.com/rds-downloads/rds-combined-ca-us-gov-bundle.pem > rds-combined-ca-bundle.pem

csplit -sk rds-combined-ca-bundle.pem "/-BEGIN CERTIFICATE-/" "{$(grep -c 'BEGIN CERTIFICATE' rds-combined-ca-bundle.pem | awk '{print $1 - 2}')}"

for CERT in xx*; do
    # extract a human-readable alias from the cert
    ALIAS=$(openssl x509 -noout -text -in $CERT |
                   perl -ne 'next unless /Subject:/; s/.*CN=//; print')
    echo "importing $ALIAS"
    
    keytool -import \
            -keystore  $CACERTS_FILE \
            -storepass changeit -noprompt \
            -alias "$ALIAS" -file $CERT
done

cd "$OLDDIR"
echo "$NEWDIR"

0

SSL mode

Happened to me because my config included sslmode=verify-full. You may need to change this to sslmode=require. Or a programatic equivalent of that.

This also applies to using SSL/TLS from applications.

For instance, a Database client in IntelliJ IDEA's. There you need to go to the connection properties, SSH/SSL tab, and set Mode to Require.

More about SSL/TLS modes e.g here: https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
-1

I created a ubuntu on my windows 10 laptop and I ran into issue when I was trying to load CMAK site download from https://github.com/yahoo/CMAK site. First it gave fatal ssl error.

openssl s_client -showcerts -servername github.com -connect github.com:443 </dev/null 2>/dev/null | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p'  > github-com.pem

and use the following command (make sure you put right path for ca-cert)

cat github-com.pem | sudo tee -a /etc/ssl/certs/ca-certificates.crt

Then use the following statement (make sure the path for cert is correct):

git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt

Then I was able to download CMAK but ran into issue when i tried ./sbt clean statement. It was giving a pkix path error. The reason is that I do not have my company issue cert stored in my cacert file.

I have downloaded the company cert (google on how to do it) and followed this article to add my downloaded cert to cacert file. Used sudo update-ca-certificates one more time before ./sbt. It worked for me.

Note: You may have to switch between root and exit when you are following above steps.

Mark W
  • 9
  • 3
-1

This is what I did.

I wanted to develop the app on Java 10, and I had the Eclipse IDE 2020-06. The cert import solution did not work for me. So then I installed Java 11 JDK, switched to the latest Eclipse IDE (which runs on Java 11), and made sure that the source-code still gets compiled against the Java 10, by adding these statemements under Maven POM:

    <maven.compiler.target>1.10</maven.compiler.target>
    <maven.compiler.source>1.10</maven.compiler.source>
    <maven.compiler.release>10</maven.compiler.release>

And it works like a charm; no errors.

ucas
  • 417
  • 1
  • 11
  • 30