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

前端 未结 23 1057
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 04:44

I have a class that will download a file from a https server. When I run it, it returns a lot of errors. It seems that I have a problem with my certificate

相关标签:
23条回答
  • 2020-11-22 04:48

    I had the same problem with the certificates error and was because of SNI, and http client that I used didn't had SNI implemented. So an version update did the job

       <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.6</version>
        </dependency>
    
    0 讨论(0)
  • 2020-11-22 04:50
    1. Export the SSL certificate using Firefox. You can export it by hitting the URL in the browser and then select the option to export the certificate. Let's assume the cert file name is your.ssl.server.name.crt
    2. Go to your JRE_HOME/bin or JDK/JRE/bin
    3. Type the command
    4. keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
    5. Restart your Java process
    0 讨论(0)
  • 2020-11-22 04:53

    Quoting from No more 'unable to find valid certification path to requested target'

    when trying to open an SSL connection to a host using JSSE. What this usually means is that the server is using a test certificate (possibly generated using keytool) rather than a certificate from a well known commercial Certification Authority such as Verisign or GoDaddy. Web browsers display warning dialogs in this case, but since JSSE cannot assume an interactive user is present it just throws an exception by default.

    Certificate validation is a very important part of SSL security, but I am not writing this entry to explain the details. If you are interested, you can start by reading the Wikipedia blurb. I am writing this entry to show a simple way to talk to that host with the test certificate, if you really want to.

    Basically, you want to add the server's certificate to the KeyStore with your trusted certificates

    Try the code provided there. It might help.

    0 讨论(0)
  • 2020-11-22 04:53

    UPDATE: That a reboot helped was coincidental (I hoped so, hooray!). The real cause of the problem was this: When Gradle is directed to use a specific keystore, that keystore must also contain all the official root certificates. Otherwise it cannot access libraries from regular repositories. What I had to do was this:

    Import the self-signed certificate:

    keytool -import -trustcacerts -alias myselfsignedcert -file /Users/me/Desktop/selfsignedcert.crt -keystore ./privateKeystore.jks
    

    Add the official root certificates:

    keytool -importkeystore -srckeystore <java-home>/lib/security/cacerts -destkeystore ./privateKeystore.jks
    

    Maybe the Gradle daemon also got in the way. Might be worth killing all running daemons found with ./gradlew --status if things start looking bleak.

    ORIGINAL POSTING:

    Nobody will believe this, I know. Still, if all else fails, give it a try: After a reboot of my Mac the problem was gone. Grrr.

    Background: ./gradlew jar kept giving me "unable to find valid certification path to requested target"

    I am stuck with a self-signed certificate, saved from browser, imported in privateKeystore.jks. Then instructed Gradle to work with privateKeystore.jks:

    org.gradle.jvmargs=-Djavax.net.debug=SSL -Djavax.net.ssl.trustStore="/Users/me/IntelliJ/myproject/privateKeystore.jks"  -Djavax.net.ssl.trustStorePassword=changeit
    

    As mentioned, this only worked after a reboot.

    0 讨论(0)
  • 2020-11-22 04:53

    first Download the ssl certificate then you can go to your java bin path execute the below command in the console.

    C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore
    
    0 讨论(0)
  • 2020-11-22 04:54

    @Gabe Martin-Dempesy's answer is helped to me. And I wrote a small script related to it. The usage is very simple.

    Install a certificate from host:

    > sudo ./java-cert-importer.sh example.com
    

    Remove the certificate that installed already.

    > sudo ./java-cert-importer.sh example.com --delete
    

    java-cert-importer.sh

    #!/usr/bin/env bash
    
    # Exit on error
    set -e
    
    # Ensure script is running as root
    if [ "$EUID" -ne 0 ]
      then echo "WARN: Please run as root (sudo)"
      exit 1
    fi
    
    # Check required commands
    command -v openssl >/dev/null 2>&1 || { echo "Required command 'openssl' not installed. Aborting." >&2; exit 1; }
    command -v keytool >/dev/null 2>&1 || { echo "Required command 'keytool' not installed. Aborting." >&2; exit 1; }
    
    # Get command line args
    host=$1; port=${2:-443}; deleteCmd=${3:-${2}}
    
    # Check host argument
    if [ ! ${host} ]; then
    cat << EOF
    Please enter required parameter(s)
    
    usage:  ./java-cert-importer.sh <host> [ <port> | default=443 ] [ -d | --delete ]
    
    EOF
    exit 1
    fi;
    
    if [ "$JAVA_HOME" ]; then
        javahome=${JAVA_HOME}
    elif [[ "$OSTYPE" == "linux-gnu" ]]; then # Linux
        javahome=$(readlink -f $(which java) | sed "s:bin/java::")
    elif [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X
        javahome="$(/usr/libexec/java_home)/jre"
    fi
    
    if [ ! "$javahome" ]; then
        echo "WARN: Java home cannot be found."
        exit 1
    elif [ ! -d "$javahome" ]; then
        echo "WARN: Detected Java home does not exists: $javahome"
        exit 1
    fi
    
    echo "Detected Java Home: $javahome"
    
    # Set cacerts file path
    cacertspath=${javahome}/lib/security/cacerts
    cacertsbackup="${cacertspath}.$$.backup"
    
    if ( [ "$deleteCmd" == "-d" ] || [ "$deleteCmd" == "--delete" ] ); then
        sudo keytool -delete -alias ${host} -keystore ${cacertspath} -storepass changeit
        echo "Certificate is deleted for ${host}"
        exit 0
    fi
    
    # Get host info from user
    #read -p "Enter server host (E.g. example.com) : " host
    #read -p "Enter server port (Default 443) : " port
    
    # create temp file
    tmpfile="/tmp/${host}.$$.crt"
    
    # Create java cacerts backup file
    cp ${cacertspath} ${cacertsbackup}
    
    echo "Java CaCerts Backup: ${cacertsbackup}"
    
    # Get certificate from speficied host
    openssl x509 -in <(openssl s_client -connect ${host}:${port} -prexit 2>/dev/null) -out ${tmpfile}
    
    # Import certificate into java cacerts file
    sudo keytool -importcert -file ${tmpfile} -alias ${host} -keystore ${cacertspath} -storepass changeit
    
    # Remove temp certificate file
    rm ${tmpfile}
    
    # Check certificate alias name (same with host) that imported successfully
    result=$(keytool -list -v -keystore ${cacertspath} -storepass changeit | grep "Alias name: ${host}")
    
    # Show results to user
    if [ "$result" ]; then
        echo "Success: Certificate is imported to java cacerts for ${host}";
    else
        echo "Error: Something went wrong";
    fi;
    
    0 讨论(0)
提交回复
热议问题