Java: sun.security.provider.certpath.SunCertPathBuilderException: ไม่สามารถค้นหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ


250

ฉันมีคลาสที่จะดาวน์โหลดไฟล์จากเซิร์ฟเวอร์https เมื่อฉันรันมันจะส่งคืนข้อผิดพลาดจำนวนมาก ดูเหมือนว่าฉันมีปัญหากับใบรับรองของฉัน เป็นไปได้หรือไม่ที่จะเพิกเฉยต่อการพิสูจน์ตัวตนของเซิร์ฟเวอร์ไคลเอ็นต์ ถ้าเป็นเช่นนั้นได้อย่างไร

package com.da;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;

import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;

public class RSDDownloadFile {
    static FileOutputStream fos;

    public void DownloadFile(String URI, String Request) throws Exception
    {
        java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
                "Lang=EN&AuthToken=package", null);
        System.out.println("URI Query: " + uri.toString());

        HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
        httpclient.start();
        try {
            Future<Boolean> future = httpclient.execute(
                    new HttpAsyncGet(uri),
                    new ResponseCallback(), null);

            Boolean result = future.get();
            if (result != null && result.booleanValue()) {
                System.out.println("\nRequest successfully executed");
            } else {
                System.out.println("Request failed");
            }              
        } 
        catch(Exception e){
            System.out.println("[DownloadFile] Exception: " + e.getMessage());
        }
        finally {
            System.out.println("Shutting down");
            httpclient.shutdown();
        }
        System.out.println("Done");  

    }

    static class ResponseCallback extends AsyncCharConsumer<Boolean> {

        @Override
        protected void onResponseReceived(final HttpResponse response) {
             System.out.println("Response: " + response.getStatusLine());
             System.out.println("Header: " + response.toString());
             try {   
                 //if(response.getStatusLine().getStatusCode()==200)
                     fos = new FileOutputStream( "Response.html" );
             }catch(Exception e){
                 System.out.println("[onResponseReceived] Exception: " + e.getMessage());
             }
        }

        @Override
        protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
            try
            {
                while (buf.hasRemaining()) 
                {
                    //System.out.print(buf.get());
                    fos.write(buf.get());
                }
            }catch(Exception e)
            {
                System.out.println("[onCharReceived] Exception: " + e.getMessage());
            }
        }

        @Override
        protected void onCleanup() {
            try
            {             
                if(fos!=null)
                    fos.close();
            }catch(Exception e){
                System.out.println("[onCleanup] Exception: " + e.getMessage());         
            }
             System.out.println("onCleanup()");
        }

        @Override
        protected Boolean buildResult() {
            return Boolean.TRUE;
        }

    }
}

ข้อผิดพลาด:

URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
    at javax.net.ssl.SSLEngine.wrap(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
    at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
    at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
    ... 9 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
    ... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 21 more
onCleanup()

[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done

2
มีอยู่ครั้งหนึ่งที่ฉันได้รับข้อผิดพลาดนี้และติดต่อทีมรักษาความปลอดภัยของเราและมันกลับกลายเป็นว่าฉันต้องแก้ไข JAR ที่เราใช้อยู่เนื่องจากทีมของเราใช้ตัวเก่าที่ บริษัท ให้มา เป็นเพียง FYI สำหรับใครก็ตามที่อาจอยู่ในสถานการณ์ที่คล้ายคลึงกัน
kayleeFrye_onDeck

คำตอบ:


215

ปัญหาปรากฏขึ้นเมื่อเซิร์ฟเวอร์ของคุณมีใบรับรองที่ลงชื่อด้วยตนเอง คุณสามารถเพิ่มใบรับรองนี้ในรายการใบรับรองที่เชื่อถือได้ของ JVM ของคุณ

ในบทความนี้ผู้เขียนอธิบายวิธีดึงใบรับรองจากเบราว์เซอร์ของคุณและเพิ่มลงในไฟล์ cacerts ของ JVM ของคุณ คุณสามารถแก้ไขJAVA_HOME/jre/lib/security/cacertsไฟล์หรือเรียกใช้แอปพลิเคชันของคุณด้วย-Djavax.net.ssl.trustStoreพารามิเตอร์ ตรวจสอบว่าคุณใช้ JDK / JRE มากเกินไปเพราะนี่มักจะเป็นแหล่งที่มาของความสับสน

ดูเพิ่มเติม: ชื่อเซิร์ฟเวอร์ใบรับรอง SSL ได้รับการแก้ไขอย่างไร / ฉันสามารถเพิ่มชื่อสำรองโดยใช้ keytool ได้อย่างไร หากเจอjava.security.cert.CertificateException: No name matching localhost foundข้อยกเว้น


3
สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันได้ติดตั้งรูทและใบรับรองลูกโซ่แล้ว แต่ Tomcat-7 ยังคงรายงาน validatorException ที่เกิดจาก "ไม่สามารถหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ" ได้ทุกวิธีในการแก้ไขปัญหานี้?
Cheruvim

ปัญหานี้ยังปรากฏขึ้นพร้อมใบรับรองที่ลงชื่อโดยบุคคลอื่นที่ไม่น่าเชื่อถือ
มาร์ควิสแห่ง Lorne

ที่ดี! มันได้ผล! อย่าลืมว่าคุณสามารถมีทั้ง jre และ jdk และทั้งคู่cacertsต้องอัปเดต
Dima Fomin

ในกรณีของฉันรูท CA อยู่ที่นั่น แต่ไม่ใช่ CA ถัดไป การเพิ่ม CA ถัดไปลงไปนั้นเป็นการหลอกลวง - ขอบคุณ
java-addict301

1
ในกรณีของฉันฉันใช้ Netbeans + Apache Tomcat (รวมอยู่ด้วย) ดังนั้นการเพิ่ม. cer ใน trust store "cacerts" บน Jdk / jre (C: \ Program Files \ Java \ jdk1.8.0_152 \ jre \ lib \ ความปลอดภัย) และ Jre (C: \ Program Files \ Java \ jre1.8.0_91 \ lib \ security) ทำงานให้ฉัน
Jnn

149

นี่คือสิ่งที่ทำงานได้อย่างน่าเชื่อถือสำหรับฉันใน macOS ตรวจสอบให้แน่ใจว่าได้แทนที่ example.com และ 443 ด้วยชื่อโฮสต์และพอร์ตจริงที่คุณพยายามเชื่อมต่อและกำหนดชื่อแทนเอง คำสั่งแรกดาวน์โหลดใบรับรองที่ให้จากเซิร์ฟเวอร์ระยะไกลและบันทึกในเครื่องในรูปแบบ x509 คำสั่งที่สองโหลดใบรับรองที่บันทึกไว้ในที่เก็บ SSL SSL ของ Java

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt
sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit

3
เหมาะกับฉันทำไม คุณต้องให้คำอธิบาย
มาร์ควิสแห่ง Lorne

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2> / dev / null) -out ~ / example.crt - คืออะไร example.crt ในคำสั่งฉันมีใบรับรอง. pem ที่ฉันต้องให้ ที่นี่ ??
พระนารายณ์ Ranganathan

3
.crt และ. pem มักใช้นามสกุลไฟล์ในรูปแบบไฟล์เดียวกัน หากคุณมีไฟล์อยู่แล้วให้รันคำสั่งที่สองแล้วส่งไปยังอาร์กิวเมนต์ -file
Gabe Martin-Dempesy

1
สิ่งที่ยอดเยี่ยม สิ่งเดียวคือ: ฉันต้องใช้ openssl 1.0.Xx ล่าสุดด้วยเหตุผลบางอย่างเก่า 9.X.Xx ไม่ทำงาน
zbstof

1
สิ่งนี้ใช้ไม่ได้กับจุดสิ้นสุด SNI สำหรับกรณีนั้นคุณต้องเพิ่ม: -servername example.com เมื่อดึงใบรับรอง
Patrik Beck

46

ฉันมีปัญหาเดียวกันกับใบรับรองตัวแทนที่ถูกต้องจากไซแมนเทค

ก่อนอื่นให้ลองรันแอปพลิเคชัน java ของคุณด้วย-Djavax.net.debug = SSLเพื่อดูว่าเกิดอะไรขึ้น

ฉันลงเอยด้วยการนำเข้าใบรับรองระดับกลางซึ่งทำให้เชนใบรับรองเสียหาย

ฉันดาวน์โหลดใบรับรองระดับกลางที่หายไปจากไซแมนเทค (คุณสามารถดูลิงค์ดาวน์โหลดไปยังใบรับรองที่ขาดหายไปในบันทึกการใช้งาน handshake ssl: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cerในกรณีของฉัน)

และฉันนำเข้าใบรับรองในที่เก็บคีย์ java หลังจากนำเข้าใบรับรองระดับกลางใบรับรอง wildcard ของฉัน SSL เริ่มทำงานในที่สุด:

keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer

นี่เป็นกรณี:
kisna

2
เพื่อหลีกเลี่ยงความสับสนให้รัน java (หรือ jcurl) ด้วยพารามิเตอร์ดีบักเพื่อดู "ห่วงโซ่ใบรับรอง" ระยะไกลในบันทึกจากนั้น grep "CN" ใน truststore ส่งผ่านอย่างชัดเจน (แทนที่จะเป็นค่าเริ่มต้น) ดังต่อไปนี้หากไม่มีอยู่คุณต้องเพิ่ม ssllabs.com/ssltest/analyze.htmlจะแสดงว่า certs ฝั่งเซิร์ฟเวอร์มีสายโซ่ที่ไม่สมบูรณ์และมีใบรับรองพา ธ การรับรองระดับกลางที่จำเป็นต้องเพิ่ม -Djavax.net.debug=ssl,handshake -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.keyStore=our-client-certs -Djavax.net.ssl.trustStoreType=jks -Djavax.net.ssl.trustStore=their-server-certs
kisna

และแน่นอนบทความอย่างเป็นทางการในการแก้ไขปัญหา SSL: docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/… blogs.oracle.com/java-platform-group/entry/ ......
kisna

ฉันมีปัญหาเดียวกันนี้มีประโยชน์มาก แต่ในกรณีของฉันคุณต้องเพิ่มใบรับรองเซิร์ฟเวอร์ไปยังไฟล์ cacerts ของรุ่น JDK
Pigritia

โปรดทราบว่ามีเครื่องมืออื่นที่เรียกว่า portecle ซึ่งสามารถเปิดไฟล์ cacert (ที่เก็บใบรับรอง) และนำเข้าใบรับรองได้อย่างง่ายดาย เพียงจำไว้ว่าให้บันทึกไฟล์ cacert หลังจากนั้น
will824

41
  1. ส่งออกใบรับรอง SSL โดยใช้ Firefox คุณสามารถส่งออกได้โดยกดปุ่ม URL ในเบราว์เซอร์แล้วเลือกตัวเลือกเพื่อส่งออกใบรับรอง สมมติว่าชื่อไฟล์ใบรับรองคือyour.ssl.server.name.crt
  2. ไปที่JRE_HOME/binหรือของคุณJDK/JRE/bin
  3. พิมพ์คำสั่ง
  4. keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
  5. รีสตาร์ทกระบวนการ Java ของคุณ

13
หากถูกถามรหัสผ่านให้ใช้รหัสผ่าน cacerts keystore ที่เป็นค่าเริ่มต้นchangeit( stackoverflow.com/a/22782035/1304830 ) ตรวจสอบให้แน่ใจว่าเรียกใช้ cmd ในฐานะผู้ดูแลระบบ
Fr4nz

22

@Gabe Martin-Dempesy ช่วยฉันได้ไหม และฉันก็เขียนบทเล็ก ๆ ที่เกี่ยวข้องกับมัน การใช้งานง่ายมาก

ติดตั้งใบรับรองจากโฮสต์:

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

ลบใบรับรองที่ติดตั้งแล้ว

> 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;

ทำงานได้อย่างไม่มีที่ติ เยี่ยมมาก! . นี่คือวิธีการทำงาน: เริ่มบริการ SSL ของคุณ (หากไม่ได้ทำงาน) และดำเนินการคำสั่งตามที่อธิบายไว้ (เช่น./java-cert-importer.sh example.com 1234) แค่นั้นแหละ.
2560

1
ใช้งานได้ดี ฉันได้รับข้อผิดพลาดบนเซิร์ฟเวอร์เจนกินส์ที่เชื่อมต่อกับ API ภายนอกซึ่งเปลี่ยนใบรับรองของเขาและทำให้ฉันไม่ทำงาน วิธีนี้ช่วยแก้ไขปัญหาของฉัน
user9869932

Oracle ควรให้สิ่งนี้ในตอนแรกหรือไม่เคยสร้างโซลูชัน SSL ที่น่ากลัวของตัวเอง การจัดการใบรับรอง SSL ควรเป็นงานของระบบปฏิบัติการ
Wolfgang Fahl

17

การอ้างอิงจากไม่ 'ไม่สามารถหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ'

เมื่อพยายามเปิดการเชื่อมต่อ SSL กับโฮสต์โดยใช้ JSSE สิ่งนี้มักจะหมายถึงว่าเซิร์ฟเวอร์ใช้ใบรับรองการทดสอบ (อาจสร้างโดยใช้ keytool) แทนที่จะเป็นใบรับรองจากผู้ให้บริการออกใบรับรองทางการค้าที่รู้จักกันดีเช่น Verisign หรือ GoDaddy เว็บเบราว์เซอร์แสดงกล่องโต้ตอบคำเตือนในกรณีนี้ แต่เนื่องจาก JSSE ไม่สามารถสันนิษฐานได้ว่าผู้ใช้แบบโต้ตอบแสดงขึ้นมาเพียงแค่โยนข้อยกเว้นตามค่าเริ่มต้น

การตรวจสอบใบรับรองเป็นส่วนสำคัญของความปลอดภัย SSL แต่ฉันไม่ได้เขียนรายการนี้เพื่ออธิบายรายละเอียด หากคุณมีความสนใจคุณสามารถเริ่มต้นด้วยการอ่านวิกิพีเดียประกาศแจ้ง ฉันกำลังเขียนรายการนี้เพื่อแสดงวิธีง่ายๆในการพูดคุยกับโฮสต์นั้นด้วยใบรับรองการทดสอบหากคุณต้องการจริงๆ

โดยทั่วไปคุณต้องการเพิ่มใบรับรองของเซิร์ฟเวอร์ใน KeyStore ด้วยใบรับรองที่เชื่อถือได้ของคุณ

ลองใช้รหัสที่ให้ไว้ มันอาจช่วย


5
ส่วนที่เกี่ยวกับ "การตรวจสอบความถูกต้องใบรับรองเป็นส่วนที่สำคัญมากของความปลอดภัย SSL" ไม่จำเป็นต้องเป็นเรื่องจริง SSL ให้การรับรองสองประการ: (1) การสื่อสารของคุณเป็นแบบส่วนตัวและ (2) คุณกำลังพูดคุยกับเซิร์ฟเวอร์ที่ NSA รู้จัก (:-) บางครั้งคุณสนใจ แต่ความเป็นส่วนตัวของการสนทนาเท่านั้น การรับรองแบบลงนามด้วยตนเองถือว่าใช้ได้ ดูsocial-biz.org/2011/10/16/the-anti-ssl-conspiracy
AgilePro

@AgilePro SSL ให้การรับรองสี่ประการได้แก่การรับรองความเป็นส่วนตัวความถูกต้องและความน่าเชื่อถือ มันไม่ได้ให้ความมั่นใจว่าคุณกำลังพูดคุยกับเซิร์ฟเวอร์ที่รู้จักกับ NSA การดูแลเกี่ยวกับความเป็นส่วนตัวเท่านั้นโดยไม่ต้องมีการรับรองความถูกต้องเป็นข้อขัดแย้งในแง่
มาร์ควิสแห่ง Lorne

@EJP ยอมรับว่าถ้าคุณใช้ใบรับรองไคลเอ็นต์คุณจะได้รับการตรวจสอบสิทธิ์และฉันคิดว่าเป็นไปได้ของการให้สิทธิ์ ... แต่การใช้งานส่วนใหญ่ไม่ได้มาพร้อมกับใบรับรองไคลเอ็นต์ สิ่งที่คุณจะเรียกความแตกต่างระหว่างใบรับรอง "ลงนามด้วยตนเอง" และใบรับรองจากผู้มีอำนาจลงนาม? ผู้มีอำนาจลงนามให้ "ความสมบูรณ์" หรือไม่ เรื่องตลกของฉันเกี่ยวกับ NSA คือหน่วยงานที่ลงนามทั้งหมดไม่สามารถรับประกันความเป็นอิสระจากทุกสิ่งได้ ไม่ใช่ความหวาดระแวงนั้นจริงๆ แต่ประเด็นคือใบรับรองของคุณเป็นเพียงความลับเท่าที่ผู้มีอำนาจลงนามสามารถสร้างได้ การลงนามด้วยตนเองอาจเป็นความลับมากกว่า
AgilePro

@AgilePro การใช้ใบรับรองเซิร์ฟเวอร์รับรองความถูกต้องของเซิร์ฟเวอร์และจำเป็นต้องทำให้ SSL มีความปลอดภัยตามที่ระบุไว้ใน RFC 2246 ใบรับรองไม่ได้เป็นความลับเลย: ดังนั้นความคิดเห็นของคุณจึงไม่เหมาะสม
มาร์ควิสแห่ง Lorne

6

นี่เป็นการแก้ไขปัญหาของฉัน

เราจำเป็นต้องนำเข้าใบรับรองไปยัง java ท้องถิ่น ถ้าไม่เราจะได้รับข้อยกเว้นด้านล่าง

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: การสร้างเส้นทาง PKIX ล้มเหลว: sun.security.provider.certpath.SunCertPathBuilderException: ไม่สามารถค้นหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ
        ที่ sun.security.ssl.Alerts.getSSLException (Alerts.java:192)
        ที่ sun.security.ssl.SSLSocketImpl.fatal (SSLSocketImpl.java:1949)
        ที่ sun.security.ssl.Handshaker.fatalSE (Handshaker.java:302)

SSLPOKEเป็นเครื่องมือที่คุณสามารถทดสอบการเชื่อมต่อ https จากเครื่องท้องถิ่นของคุณ

คำสั่งเพื่อทดสอบการเชื่อมต่อ:

"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
    sun.security.validator.ValidatorException: การสร้างเส้นทาง PKIX ล้มเหลว: 
    sun.security.provider.certpath.SunCertPathBuilderException: ไม่สามารถค้นหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ
        ที่ sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:387)
        ที่ sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:292)
        ที่ sun.security.validator.Validator.validate (Validator.java:260)
        ที่ sun.security.ssl.X509TrustManagerImpl.validate (X509TrustManagerImpl.java:324)
        ที่ sun.security.ssl.X509TrustManagerImpl.checkTrusted (X509TrustManagerImpl.java:229)
        ที่ sun.security.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:124)
        ที่ sun.security.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:1496)
        ที่ sun.security.ssl.ClientHandshaker.processMessage (ClientHandshaker.java:216)
        ที่ sun.security.ssl.Handshaker.processLoop (Handshaker.java:1026)
        at sun.security.ssl.Handshaker.process_record (Handshaker.java:961)
        ที่ sun.security.ssl.SSLSocketImpl.readRecord (SSLSocketImpl.java:1062)
        ที่ sun.security.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1375)
        ที่ sun.security.ssl.SSLSocketImpl.writeRecord (SSLSocketImpl.java:747)
        ที่ sun.security.ssl.AppOutputStream.write (AppOutputStream.java:123)
        ที่ sun.security.ssl.AppOutputStream.write (AppOutputStream.java:138)
        ที่ SSLPoke.main (SSLPoke.java:31)
    เกิดจาก: sun.security.provider.certpath.SunCertPathBuilderException: ไม่สามารถหาเส้นทางการรับรองที่ถูกต้องไปยัง 
    เป้าหมายที่ร้องขอ
        ที่ sun.security.provider.certpath.SunCertPathBuilder.build (SunCertPathBuilder.java:141)
        ที่ sun.security.provider.certpath.SunCertPathBuilder.engineBuild (SunCertPathBuilder.java:126)
        ที่ java.security.cert.CertPathBuilder.build (CertPathBuilder.java:280)
        ที่ sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:382)
        ... อีก 15
keytool -import -alias <anyname> -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file <cert path>

สิ่งนี้จะแจ้งให้ "ใส่รหัสผ่านที่เก็บคีย์:" changeitเป็นรหัสผ่านเริ่มต้น และในที่สุดพรอมต์ "เชื่อถือใบรับรองนี้ [ไม่]:", ให้ "ใช่" เพื่อเพิ่มใบรับรองให้กับที่เก็บคีย์

ยืนยันบัญชี:

C:\tools>"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
Successfully connected    

5

ฉันสามารถทำให้มันทำงานกับรหัสเท่านั้นคือไม่จำเป็นต้องใช้ keytool:

import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Test
{
    private static final DynamicIntProperty MAX_TOTAL_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty ROUTE_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty CONNECT_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connect.timeout", 60000);
    private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.socket.timeout", -1);
    private static final DynamicIntProperty CONNECTION_REQUEST_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connectionrequest.timeout", 60000);
    private static final DynamicBooleanProperty STALE_CONNECTION_CHECK = DynamicPropertyFactory.getInstance().getBooleanProperty("X.checkconnection", true);

    public static void main(String[] args) throws Exception
    {

        SSLContext sslcontext = SSLContexts.custom()
                .useTLS()
                .loadTrustMaterial(null, new TrustStrategy()
                {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
                    {
                        return true;
                    }
                })
                .build();
        SSLIOSessionStrategy sslSessionStrategy = new SSLIOSessionStrategy(sslcontext, new AllowAll());

        Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create()
                .register("http", NoopIOSessionStrategy.INSTANCE)
                .register("https", sslSessionStrategy)
                .build();

        DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.DEFAULT);
        PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry);
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS.get());
        connectionManager.setDefaultMaxPerRoute(ROUTE_CONNECTIONS.get());

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIMEOUT.get())
                .setConnectTimeout(CONNECT_TIMEOUT.get())
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT.get())
                .setStaleConnectionCheckEnabled(STALE_CONNECTION_CHECK.get())
                .build();

        CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
                .setSSLStrategy(sslSessionStrategy)
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        httpClient.start();

        // use httpClient...
    }

    private static class AllowAll implements X509HostnameVerifier
    {
        @Override
        public void verify(String s, SSLSocket sslSocket) throws IOException
        {}

        @Override
        public void verify(String s, X509Certificate x509Certificate) throws SSLException {}

        @Override
        public void verify(String s, String[] strings, String[] strings2) throws SSLException
        {}

        @Override
        public boolean verify(String s, SSLSession sslSession)
        {
            return true;
        }
    }
}

1
Btw ฉันใช้ httpasyncclient: 4.0.1
Jonas Bergström

ฉันต้องการสิ่งที่คล้ายกัน @ JonasBergströmโซลูชันของคุณกับ SSLContext ช่วยได้มาก
EnterSB

8
โปรดทราบว่าวิธีนี้ไม่ปลอดภัย
มาร์ควิสแห่ง Lorne

ขอบคุณ Jonas วิธีแก้ปัญหาของคุณแก้ปัญหาได้ แต่ฉันคิดว่ามันใช้เวลานานมาก (3 - 5 วินาที) ในการสร้างการเชื่อมต่อครั้งแรกหลังจากนั้นทุกการเชื่อมต่อต้องการเพียง 300-400 มิลลิวินาที
twcai

5

แหล่งที่มาของข้อผิดพลาดนี้ในอินสแตนซ์ Apache 2.4 ของฉัน (โดยใช้ใบรับรองตัวแทน Comodo) เป็นเส้นทางที่ไม่สมบูรณ์ไปยังใบรับรองหลักที่ลงนามโดย SHA-1 มีโซ่หลายในใบรับรองที่ออกและห่วงโซ่ที่นำไปสู่ใบรับรองหลัก SHA-1 หายไปใบรับรองระดับกลาง เบราว์เซอร์สมัยใหม่รู้วิธีจัดการกับสิ่งนี้ แต่ Java 7 ไม่สามารถจัดการได้ตามค่าเริ่มต้น (แม้ว่าจะมีวิธีการที่ซับซ้อนในการทำสิ่งนี้ในโค้ด) ผลลัพธ์คือข้อความแสดงข้อผิดพลาดที่มีลักษณะเหมือนกับกรณีของใบรับรองที่ลงนามเอง:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 22 more

ในกรณีนี้ข้อความ "ไม่สามารถค้นหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ" กำลังถูกสร้างขึ้นเนื่องจากใบรับรองระดับกลางที่ขาดหายไป คุณสามารถตรวจสอบใบรับรองที่ขาดหายไปโดยใช้การทดสอบSSL Labsกับเซิร์ฟเวอร์ เมื่อคุณพบใบรับรองที่เหมาะสมแล้วให้ดาวน์โหลดและ (หากเซิร์ฟเวอร์อยู่ภายใต้การควบคุมของคุณ) ให้เพิ่มลงในบันเดิลใบรับรอง หรือคุณสามารถนำเข้าใบรับรองที่หายไปภายในเครื่อง รองรับปัญหานี้บนเซิร์ฟเวอร์เป็นวิธีแก้ไขปัญหาทั่วไปเพิ่มเติม


ssllabs.com/ssltestเป็นผู้ช่วยเหลือเพียงแค่ต้องเปรียบเทียบกับการตรวจสอบใบรับรองการทำงาน
kisna

5

สำหรับ Windows เท่านั้นให้ทำตามขั้นตอนเหล่านี้:

  1. ใน Chrome ไปที่การตั้งค่า
  2. ในการตั้งค่าคลิกแสดงการตั้งค่าขั้นสูง
  3. ภายใต้ HTTPS / SSL คลิกที่จัดการใบรับรอง
  4. ส่งออกใบรับรองของคุณ
  5. ใน Windows ค้นหา (กดปุ่ม windows บนแป้นพิมพ์) พิมพ์ java
  6. เลือก (กำหนดค่า Java) ตัวเลือกซึ่งจะเปิด Java Control Panel
  7. เลือกแท็บความปลอดภัยในแผงควบคุม Java
  8. เลือกจัดการใบรับรอง
  9. คลิกนำเข้า
  10. ภายใต้แท็บ (ผู้ใช้) ที่เลือกและประเภทใบรับรองเป็น (ใบรับรองที่เชื่อถือได้)
  11. คลิกปุ่มนำเข้าและเรียกดูใบรับรองที่ดาวน์โหลดและนำเข้า

4

สำหรับผู้ที่ชื่นชอบ Debian และ Java prepackaged:

sudo mkdir /usr/share/ca-certificates/test/  # don't mess with other certs
sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/
sudo dpkg-reconfigure --force ca-certificates  # check your cert in curses GUI!
sudo update-ca-certificates --fresh --verbose

อย่าลืมตรวจสอบ/etc/default/cacerts:

# enable/disable updates of the keystore /etc/ssl/certs/java/cacerts
cacerts_updates=yes

วิธีลบใบรับรอง:

sudo rm /usr/share/ca-certificates/test/test.loc.crt
sudo rm /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh --verbose

2

สิ่งนี้อาจเกิดจากการใช้ GoDaddy certs กับ Java 7 ที่ลงชื่อโดยใช้ SHA2

Chrome และเบราว์เซอร์อื่น ๆ ทั้งหมดเริ่มที่จะเลิกใช้ใบรับรอง SSL ที่ลงชื่อโดยใช้ SHA1 เนื่องจากไม่ปลอดภัย

ดูข้อมูลเพิ่มเติมเกี่ยวกับปัญหาได้ที่นี่รวมถึงวิธีแก้ไขปัญหาบนเซิร์ฟเวอร์ของคุณหากคุณต้องการ


2

ฉันมีปัญหาเดียวกันกับข้อผิดพลาดใบรับรองและเป็นเพราะ SNI และไคลเอนต์ http ที่ฉันใช้ไม่ได้มีการใช้ SNI ดังนั้นการอัปเดตเวอร์ชันจึงทำงานได้

   <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.6</version>
    </dependency>

2

UPDATE:การรีบูตช่วยโดยบังเอิญ (ฉันหวังอย่างนั้นไชโย!) สาเหตุที่แท้จริงของปัญหาคือ: เมื่อ Gradle สั่งให้ใช้ที่เก็บคีย์เฉพาะที่เก็บคีย์นั้นต้องมีใบรับรองรูทอย่างเป็นทางการทั้งหมดด้วย มิฉะนั้นจะไม่สามารถเข้าถึงไลบรารีจากที่เก็บปกติ สิ่งที่ฉันต้องทำคือ:

อิมพอร์ตใบรับรองที่ลงนามเอง:

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

เพิ่มใบรับรองรูทอย่างเป็นทางการ:

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

บางที Gradle daemon ก็เข้ามาขวางทางเช่นกัน อาจคุ้มค่าที่จะฆ่า daemons ที่กำลังวิ่งอยู่./gradlew --statusหากพบว่าสิ่งต่าง ๆ เริ่มดูไร้ชีวิตชีวา

โพสต์ต้นฉบับ:

ไม่มีใครจะเชื่อเรื่องนี้ฉันรู้ แต่ถ้าทุกอย่างล้มเหลวลองทำดู: หลังจากรีบูตเครื่อง Mac ของฉันแล้วปัญหาก็หายไป ฮึ่ม

พื้นหลัง: ./gradlew jar ให้ฉัน "ไม่สามารถหาเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ"

ฉันติดอยู่กับใบรับรองที่ลงนามเองบันทึกจากเบราว์เซอร์นำเข้าใน privateKeystore.jks จากนั้นสั่งให้ Gradle ทำงานกับ privateKeystore.jks:

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

ดังที่กล่าวมาสิ่งนี้ใช้ได้เฉพาะหลังจากรีบูต


2

AVG เวอร์ชัน 18.1.3044 (พร้อม Windows 10) รบกวนการใช้งานแอพพลิเคชั่น Spring ในพื้นที่ของฉัน

โซลูชัน:ป้อนในส่วน AVG ชื่อ "เว็บและอีเมล" และปิดใช้งาน "การป้องกันอีเมล" AVG บล็อกใบรับรองหากไซต์ไม่ปลอดภัย


2

ตรวจสอบให้แน่ใจว่าhttps://176.66.3.69:6443/มีใบรับรองที่ถูกต้อง คุณสามารถตรวจสอบผ่านเบราว์เซอร์ก่อนhttps ไม่ปลอดภัยถ้ามันทำงานในเบราว์เซอร์มันจะทำงานในจาวา

ที่ทำงานให้ฉัน


และฉันควรทำอย่างไรถ้าเบราว์เซอร์บ่นเช่นกัน
เจ้าพ่อ

พยายามติดตั้งใบรับรอง
Amr Ibrahim

2

มีวิธีแก้ปัญหานี้มากมาย ...

วิธีหนึ่งคือตั้งค่าใบรับรอง TrustStore ในไฟล์ที่เก็บคีย์และวางไว้ในพา ธ ของแอ็พพลิเคชันและตั้งค่าคุณสมบัติระบบเหล่านี้ในวิธีหลัก:

public static void main(String[] args) {
  System.setProperty("javax.net.ssl.trustStore", "trust-store.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "TrustStore");
  ...
}

วิธีอื่นคือวางที่เก็บคีย์เป็นไฟล์รีซอร์สภายในไฟล์ jar ของโครงการและโหลด:

public static SSLContext createSSLContext(String resourcePath, String pass) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
  // initialise the keystore
  final char[] password = pass.toCharArray();
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(ThisClass.class.getResourceAsStream(resourcePath
  ), password);

  // Setup the key manager factory.
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  kmf.init(ks, password);

  // Setup the trust manager factory.
  TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
  tmf.init(ks);

  SSLContext sslc = SSLContext.getInstance("TLS");
  sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  return sslc;
}

public static void main(String[] args) {
  SSLContext.setDefault(
    createSSLContext("/trust-store.jks", "TrustStore"));
  ...
}

ใน windows คุณสามารถลองวิธีนี้ได้เช่นกัน: https://stackoverflow.com/a/59056537/980442


ฉันสร้างไฟล์ที่เก็บคีย์จาก.crtไฟล์CA ผู้มีสิทธิ์ออกใบรับรองด้วยวิธีนี้:

keytool -import -alias ca -keystore trust-store.jks -storepass TrustStore -trustcacerts -file ca.crt

FYI: https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient.html


1

คุณมีสองตัวเลือกนำเข้าใบรับรองที่ลงนามเองไปยังที่เก็บคีย์ของ java สำหรับ jvm แต่ละซอฟต์แวร์จะทำงานหรือลองใช้ ssl factory ที่ไม่ผ่านการตรวจสอบ:

jdbc:postgresql://myserver.com:5432/mydatabasename?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

1

มีปัญหาเช่นภาพนี้

ป้อนคำอธิบายรูปภาพที่นี่

พยายามแก้ไขปัญหาบางอย่าง แต่พบว่าแม้ว่าจะเป็นโครงการเดียวกันเมื่ออยู่ในสถานที่ทำงานของคนอื่น แต่ก็ไม่เป็นไร ไม่จำเป็นต้องตั้งค่าเพิ่มเติม ดังนั้นเราจึงเดาได้ว่ามันเป็นปัญหาสิ่งแวดล้อม เราลองเปลี่ยนรุ่น JDK, IDE แต่ไม่ได้ผล การสอบสวนใช้เวลาประมาณ 4 ชั่วโมงจนกว่าเราจะลองคำตอบที่ได้รับคะแนนสูงสุด ฉันไม่พบข้อผิดพลาดที่กล่าวถึงในคำตอบนั้น แต่ฉันพบผ่านเบราว์เซอร์ของฉันเกี่ยวกับ HTTP URL (ล็อก) ว่ามีการรับรองของ Charles จากนั้นฉันก็รู้ว่า charles ของฉันอยู่ตลอดเวลา ตราบใดที่ฉันปิดมันก็ทำงานได้ดี

ดังนั้นฉันจึงทิ้งประสบการณ์ที่อาจมีประโยชน์สำหรับกรณีของคุณ


0

ในกรณีของฉันฉันใช้ MacOs High Sierra กับ Java 1.6 ไฟล์ cacert นั้นอยู่ในตำแหน่งที่แตกต่างจากคำตอบของ Gabe Martin-Dempesy ไฟล์ cacert ยังเชื่อมโยงไปยังตำแหน่งอื่นแล้ว (/ Library / Internet Plug-In / JavaAppletPlugin.plugin / Contents / Home / lib / security / cacerts)

ใช้ FireFox ฉันส่งออกใบรับรองจากเว็บไซต์ที่เป็นปัญหาไปยังไฟล์ภายในเครื่องที่เรียกว่า "ส่งออกใบรับรอง" จากนั้นฉันใช้ keytool เพื่อย้ายใบรับรองไปยังไฟล์ cacert วิธีนี้แก้ไขปัญหาได้

bash-3.2# cd /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/
bash-3.2# keytool -importcert -file ~/exportedCertFile.crt -alias example -keystore cacerts -storepass changeit

0

ก่อนดาวน์โหลดใบรับรอง SSL จากนั้นคุณสามารถไปที่เส้นทาง java bin ของคุณดำเนินการคำสั่งด้านล่างในคอนโซล

C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore

-1

ในกรณีของฉันฉันมีทั้ง keystore และ truststore ที่มีใบรับรองเดียวกันดังนั้นการลบ truststore ช่วย บางครั้งห่วงโซ่ใบรับรองอาจเป็นปัญหาหากคุณมีหลายสำเนาใบรับรอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.