ไม่พบเส้นทางการรับรองที่ถูกต้องไปยังเป้าหมายที่ร้องขอ - ข้อผิดพลาดแม้หลังจากที่ใบรับรองนำเข้าแล้ว


205

ฉันมีไคลเอนต์ Java พยายามเข้าถึงเซิร์ฟเวอร์ด้วยใบรับรองแบบลงนามด้วยตนเอง

เมื่อฉันพยายามโพสต์ไปยังเซิร์ฟเวอร์ฉันได้รับข้อผิดพลาดต่อไปนี้:

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

หลังจากทำวิจัยเกี่ยวกับปัญหาแล้วฉันก็ทำสิ่งต่อไปนี้

  1. บันทึกชื่อโดเมนเซิร์ฟเวอร์ของฉันเป็นroot.cerไฟล์
  2. ใน JRE ของเซิร์ฟเวอร์ Glassfish ของฉันฉันรันสิ่งนี้:
    keytool -import -alias example -keystore cacerts -file root.cer
  3. ในการตรวจสอบใบรับรองถูกเพิ่มไปยัง cacert ของฉันสำเร็จฉันทำสิ่งนี้:
    keytool -list -v -keystore cacerts
    ฉันเห็นว่าใบรับรองนั้นมีอยู่
  4. จากนั้นฉันเริ่ม Glassfish ใหม่และยกเลิก 'โพสต์'

ฉันยังคงได้รับข้อผิดพลาดของงา

ฉันมีความรู้สึกเช่นนี้เพราะ Glassfish ของฉันไม่ได้อ่านไฟล์ cacert ที่ฉันได้แก้ไข แต่อาจมีบางอัน

คุณเคยมีปัญหานี้บ้างหรือไม่และสามารถผลักฉันไปในทิศทางที่ถูกต้องได้หรือไม่


1
เพียงเพื่อชี้แจง "ฉันมีไคลเอนต์ Java พยายามเข้าถึงเซิร์ฟเวอร์ด้วยใบรับรองที่ลงนามเอง": คุณกำลังพูดถึงการใช้ใบรับรองไคลเอ็นต์ที่ลงนามด้วยตนเองใช่ไหม? มีการกำหนดค่าเฉพาะสำหรับการตั้งค่าตัวเชื่อมต่อของคุณใน Glassfish (โดยเฉพาะอย่างยิ่งการตั้งค่าร้านค้าที่เชื่อถือได้)?
บรูโน่

"ฉันมีไคลเอนต์ Java ที่พยายามเข้าถึงเซิร์ฟเวอร์ที่มีใบรับรองแบบลงนามด้วยตนเอง": คุณกำลังพูดถึงการใช้ใบรับรองไคลเอ็นต์ที่ลงชื่อด้วยตนเองใช่ไหม? - ใช่
TheCoder

1
ฉันพบการตั้งค่า 2 รายการใน Glassfish JVM: -Djavax.net.ssl.keyStore = $ {com.sun.aas.instanceRoot} /config/keystore.jks และ -Djavax.net.ssl.trustStore = $ {com.sun aas.instanceRoot} /config/cacerts.jks ตอนนี้ฉันต้องเพิ่มใบรับรองไปยังหนึ่งในนั้น คุณสามารถยืนยันได้ว่าเป็นที่เก็บคีย์ที่ฉันเพิ่มเข้าไปหรือไม่
TheCoder

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

นั่นใช้ได้กับ Bruno ฉันเพิ่มไปยังที่เก็บ Glassfish ของฉัน ขอบคุณมากสำหรับความช่วยเหลือของคุณ คุณก็เดิร์ค
TheCoder

คำตอบ:


155

น่าเสียดายที่อาจมีหลายสิ่งหลายอย่างและเซิร์ฟเวอร์แอปจำนวนมากและ 'ตัวห่อหุ้ม' ของจาวาอื่น ๆ มีแนวโน้มที่จะเล่นกับคุณสมบัติต่างๆ ดังนั้นอาจมองสิ่งที่แตกต่างอย่างสิ้นเชิง

ข้อผิดพลาดสั้น ๆ - ฉันลอง:

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

เพื่อดูว่าช่วย แทนที่จะใช้ 'ทั้งหมด' ก็สามารถตั้งค่าเป็น 'ssl' ผู้จัดการหลักและผู้จัดการที่ไว้วางใจซึ่งอาจช่วยคุณได้ การตั้งค่าเป็น 'ช่วย' จะแสดงรายการดังนี้ด้านล่างบนแพลตฟอร์มส่วนใหญ่

โดยไม่คำนึงถึง - ให้แน่ใจว่าคุณเข้าใจความแตกต่างระหว่างที่เก็บคีย์ (ซึ่งคุณมีคีย์ส่วนตัวและใบรับรองที่คุณพิสูจน์ตัวตนของคุณด้วย) และที่เก็บความเชื่อถือ (ซึ่งกำหนดผู้ที่คุณไว้วางใจ) - และความจริงที่ว่า มี 'ห่วงโซ่' ของความไว้วางใจต่อรูท - ซึ่งแยกจากเชนใด ๆ กับรูทที่คุณต้องหาว่าใครคือใคร

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

ที่มา: # ดูhttp://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#Debug


6
ขอบคุณมาก! -Djavax.net.ssl.trustStore = / location_of / trustStore แก้ไขปัญหาของฉันและข้อมูลการดีบักก็มีประโยชน์เช่นกัน
RHE

5
java -Djavax.net.debug = all -Djavax.net.ssl.trustStore = trustStore ... ให้ข้อผิดพลาดด้านล่าง: ข้อผิดพลาด: ไม่สามารถค้นหาหรือโหลดคลาสหลัก ...
rohith

1
แน่นอนคุณอาจต้องระบุรหัสผ่านของ truststore ด้วย -Djavax.net.ssl.trustStorePassword = changeit
user1754036

18

นี่คือวิธีการแก้ปัญหาตามลิงค์ด้านล่างทีละขั้นตอน:

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

JAVA FILE: หายไปจากบล็อก

/*
 * 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);
    }
    }

}

3
วิธีนี้ใช้ได้ผลสำหรับฉัน แต่มันต้องการการเปลี่ยนแปลงเล็กน้อยในคลาสส่วนตัว SavingTrustManager:public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0];}
Richard

1
@ Richard, @ Paul, @ user6258309 ฉันได้รับข้อผิดพลาดยกเว้นในหัวข้อ "main" java.net.SocketTimeoutException: อ่านหมดเวลาที่ java.net.SocketInputStream.socketRead0 (วิธีเนทีฟ) ที่ java.net.SocketInputStream.socketRead (ไม่ทราบแหล่งที่มา ) ฉันจะแก้ไขได้อย่างไร
Renjith Krishnan

5
นี้ 'ดังนั้น; lution' ไม่ปลอดภัยอย่างรุนแรง ไม่ได้ใช้.
มาร์ควิสแห่ง Lorne

9
คำตอบนี้ส่วนใหญ่เป็นรหัส มันไม่ได้อธิบายว่าทำไมหรือทำไมมันไม่ทำงาน

13

คุณต้องกำหนดค่าคุณสมบัติระบบ JSSE โดยเฉพาะชี้ไปที่ที่เก็บใบรับรองลูกค้า

ผ่านทางบรรทัดคำสั่ง:

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

หรือผ่านรหัส Java:

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

สำหรับข้อมูลเพิ่มเติมโปรดดูที่รายละเอียดเกี่ยวกับเว็บไซต์ RedHat


มีปัญหาเดียวกันกับ Spring Boot, microservices Spring Cloud และใบรับรอง SSL ที่ลงชื่อด้วยตนเอง ฉันสามารถตั้งค่า keyStore และ keyStorePassword ใน application.properties และทำให้มันทำงานแบบนั้นนอกกรอบ แต่ก็ไม่ประสบความสำเร็จในการทำเช่นเดียวกันกับ trustStore และ trustStorePassword คำตอบนี้ใช้ได้สำหรับฉันสำหรับ trust store
Mate Šimović

7

(repost จากการตอบสนองอื่น ๆ ของฉัน )
ใช้ยูทิลิตี้ CLI keytoolจากการกระจายซอฟต์แวร์จาวาสำหรับการนำเข้า (และความไว้วางใจ! ) ใบรับรองจำเป็น

ตัวอย่าง:

  1. จาก cli เปลี่ยน dir เป็น jre \ bin

  2. ตรวจสอบ keystore (พบไฟล์ในไดเร็กทอรี
    jre \ bin) keytool -list -keystore .. \ lib \ security \ cacerts
    รหัสผ่านถูกเปลี่ยน

  3. ดาวน์โหลดและบันทึกใบรับรองทั้งหมดในเครือจากเซิร์ฟเวอร์ที่ต้องการ

  4. เพิ่มใบรับรอง (ก่อนที่จะต้องลบแอตทริบิวต์ "อ่านอย่างเดียว" ในไฟล์ ".. \ lib \ security \ cacerts"), เรียกใช้: keytool -alias REPLACE_TO_ANY_UNIQ_NAME -import -keystore .. \ lib \ security \ cacerts -file "r: \ root.crt"

ฉันบังเอิญพบเคล็ดลับง่ายๆ โซลูชันอื่น ๆ ต้องการใช้ InstallCert.Java และ JDK

แหล่งที่มา: http://www.java-samples.com/showtutorial.php?tutorialid=210


6

ผมมีปัญหาเดียวกันกับSBT
มันพยายามดึงการอ้างอิงจากrepo1.maven.orgมากกว่า ssl
แต่กล่าวว่าเป็น "ไม่สามารถหาเส้นทางการรับรองที่ถูกต้องไปยัง URL เป้าหมายที่ร้องขอ"
ดังนั้นฉันจึงติดตามโพสต์นี้ และยังไม่สามารถตรวจสอบการเชื่อมต่อได้
ดังนั้นผมจึงอ่านเกี่ยวกับเรื่องนี้และพบว่าใบรับรองรากไม่เพียงพอตามที่ได้รับการแนะนำโดยการโพสต์ดังนั้น -
สิ่งที่ทำงานให้ฉันถูกนำเข้าใบรับรอง CA กลางเข้าไปเก็บคีย์
ฉันเพิ่มใบรับรองทั้งหมดในห่วงโซ่จริง ๆ และใช้งานได้ดี


4

โซลูชันเมื่อย้ายจาก JDK 8 เป็น 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

ขั้นตอนในการแก้ไข

  • ฉันลบใบรับรอง JDK 10 และแทนที่ด้วย JDK 8
  • เนื่องจากฉันกำลังสร้างอิมเมจ Docker ฉันสามารถทำได้อย่างรวดเร็วโดยใช้การสร้างหลายขั้นตอน
    • ฉันกำลังสร้าง JRE ให้น้อยที่สุดโดยใช้jlinkเป็น/opt/jdk/bin/jlink \ --module-path /opt/jdk/jmods...

ดังนั้นนี่คือเส้นทางที่แตกต่างและลำดับของคำสั่ง ...

# 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

2

ฉันทำงานเกี่ยวกับการสอนเกี่ยวกับบริการเว็บ REST ที่ www.udemy.com (REST Java Web Services) ตัวอย่างในบทช่วยสอนบอกว่าเพื่อให้มี SSL เราต้องมีโฟลเดอร์ชื่อ "trust_store" ในโครงการ "ลูกค้า" คราสของฉันที่ควรมีไฟล์ "ที่เก็บคีย์" (เรามีโครงการ "ลูกค้า" เพื่อเรียกใช้บริการ และ "บริการ" โครงการที่มีบริการเว็บ REST - 2 โครงการในเวิร์กสเปซ eclipse เดียวกันหนึ่งไคลเอ็นต์ไคลเอ็นต์บริการอื่น ๆ ) เพื่อให้ง่ายขึ้นพวกเขาบอกว่าจะคัดลอก "keystore.jks" จากเซิร์ฟเวอร์แอพ glassfish (glassfish \ domains \ domain1 \ config \ keystore.jks) เรากำลังใช้และใส่ลงในโฟลเดอร์ "trust_store" ที่พวกเขาทำให้ฉัน โครงการลูกค้า ดูเหมือนว่าเหมาะสมแล้ว: certs ที่ลงชื่อด้วยตนเองในเซิร์ฟเวอร์ ' s key_store จะสอดคล้องกับ certs ใน client trust_store ตอนนี้การทำเช่นนี้ฉันได้รับข้อผิดพลาดที่โพสต์ต้นฉบับกล่าวถึง ฉันได้ทำสิ่งนี้และอ่านว่าข้อผิดพลาดเกิดจากไฟล์ "keystore.jks" บนไคลเอ็นต์ที่ไม่มีใบรับรองที่เชื่อถือได้ / ลงนามว่าใบรับรองที่พบนั้นเป็นแบบลงนามด้วยตนเอง

เพื่อให้สิ่งต่าง ๆ ชัดเจนขอให้ฉันบอกว่าตามที่ฉันเข้าใจแล้ว "keystore.jks" มีใบรับรองที่ลงชื่อด้วยตนเองและไฟล์ "cacerts.jks" มี CA certs (เซ็นชื่อโดย CA) "keystore.jks" คือ "keystore" และ "cacerts.jks" คือ "trust store" ในฐานะที่เป็น "Bruno" ผู้วิจารณ์กล่าวถึงข้างต้นว่า "keystore.jks" เป็นของท้องถิ่นและ "cacerts.jks" สำหรับลูกค้าระยะไกล

ดังนั้นฉันพูดกับตัวเองเฮ้ glassfish ยังมีไฟล์ "cacerts.jks" ซึ่งเป็นไฟล์ trust_store ของ glassfish cacerts.jsk ควรจะมีใบรับรอง CA และเห็นได้ชัดว่าฉันต้องการโฟลเดอร์ trust_store ของฉันเพื่อเก็บไฟล์เก็บกุญแจที่มีใบรับรอง CA อย่างน้อยหนึ่งใบ ดังนั้นฉันจึงลองวางไฟล์ "cacerts.jks" ในโฟลเดอร์ "trust_store" ที่ฉันได้ทำไว้ในโครงการลูกค้าของฉันและเปลี่ยนคุณสมบัติ VM ให้ชี้ไปที่ "cacerts.jks" แทนที่จะเป็น "keystore.jks" ที่กำจัดข้อผิดพลาด ฉันเดาว่าทุกอย่างที่จำเป็นคือใบรับรอง CA ในการทำงาน

สิ่งนี้อาจไม่เหมาะสำหรับการผลิตหรือแม้แต่การพัฒนาเกินกว่าจะได้อะไรมาทำงาน ตัวอย่างเช่นคุณอาจใช้คำสั่ง "keytool" เพื่อเพิ่ม CA certs ให้กับไฟล์ "keystore.jks" ในไคลเอนต์ แต่อย่างไรก็ตามหวังว่าอย่างน้อยนี่จะทำให้สถานการณ์ที่อาจเกิดขึ้นที่นี่แคบลงเพื่อทำให้เกิดข้อผิดพลาด

นอกจากนี้: วิธีการของฉันดูเหมือนจะมีประโยชน์สำหรับลูกค้า (เพิ่มใบรับรองเซิร์ฟเวอร์ให้กับลูกค้า trust_store) ดูเหมือนว่าความคิดเห็นด้านบนเพื่อแก้ไขการโพสต์ต้นฉบับมีประโยชน์สำหรับเซิร์ฟเวอร์ (เพิ่มใบรับรองลูกค้าไปยังเซิร์ฟเวอร์ trust_store) ไชโย

การตั้งค่าโครงการ Eclipse:

  • MyClientProject
  • src
  • ทดสอบ
  • ไลบรารีระบบ JRE
  • ...
  • trust_store
    --- cacerts.jks --- keystore.jks

ตัวอย่างจากไฟล์ MyClientProject.java:

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");
        }

  });
}

1

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


1

ในกรณีของฉันฉันกำลังเผชิญกับปัญหาเพราะในที่เก็บคีย์เฉพาะกระบวนการ Tomcat ของฉันได้รับการใช้

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

ฉันกำลังนำเข้าใบรับรองไปยัง cacert ของ JRE / lib / security และการเปลี่ยนแปลงไม่ได้สะท้อนให้เห็น จากนั้นฉันทำคำสั่งด้านล่างโดยที่ /tmp/cert1.test มีใบรับรองของเซิร์ฟเวอร์เป้าหมาย

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

เราสามารถตรวจสอบอีกครั้งว่าการนำเข้าใบรับรองสำเร็จหรือไม่

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

และดูว่าเซิร์ฟเวอร์แท็กของคุณพบกับ alias rapidssl-myserver หรือไม่


0

ตรวจสอบว่ามีไฟล์$JAVA_HOME/lib/security/cacertsอยู่หรือไม่! ในกรณีของฉันมันไม่ใช่ไฟล์ แต่เป็นลิงก์ไป/etc/ssl/certs/java/cacertsยังและนี่เป็นลิงก์ไปยังตัวเอง (WHAT ???) ดังนั้นเนื่องจาก JVM ไม่สามารถค้นหาไฟล์ได้

การแก้ไข: คัดลอกไฟล์ cacerts จริง ( คุณสามารถทำได้จาก JDK อื่น ) ไปยัง/etc/ssl/certs/java/ไดเรกทอรีและมันจะแก้ปัญหาของคุณ :)


จริง ๆ แล้ว JDK รักษาลิงค์และอาจเข้ากันได้กับ API เก่า SDKs ... ฉันประสบความสำเร็จในการทำเช่นเดียวกัน ... ฉันย้ายจาก JDK 8 ไปเป็น JDK 10 และใช้ Docker ดังนั้นฉันแค่ต้องการคัดลอก cacerts จาก ภาพไปยังอีก ... ฉันสร้างการเชื่อมโยงและวิธีการที่แน่นอนเดียวกัน ...rm -f /opt/jdk-minimal/jre/lib/security/cacerts ; ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts
Marcello de ขาย

-9

ให้บอกว่าถ้าคุณใช้ตัวแปร classpath เช่น $ {JAVA_HOME} ใน pom.xml

<target>
                    <property name="compile_classpath" refid="maven.compile.classpath"/>
                    <property name="runtime_classpath" refid="maven.runtime.classpath"/>
                    <property name="test_classpath" refid="maven.test.classpath"/>
                    <property name="plugin_classpath" refid="maven.plugin.classpath"/>
                    <property name="jaxb-api.jar" value="${maven.dependency.javax.xml.bind.jaxb-api.jar.path}"/>
                    <property name="project_home" value="${PROJECT_HOME}"/>
                    <property name="java_home" value="${JAVA_HOME}"/>
                    <property name="ant_home" value="${ANT_HOME}"/>
                    <property name="common_home" value="${COMMON_HOME}"/>
                    <property name="JAXP_HOME" value="${common_home}/lib"/>
                    <property name="ejfw_home" value="${PROJECT_HOME}/lib"/>
                    <property name="weblogic_home" value="${WL_HOME}"/>
                    <property name="fw_home" value="${FW_HOME}"/>
                    <property name="env" value="${BUILDENV}"/>
                    <property name="tokenfile" value="${BUILDENV}${BUILDENV_S2S}.properties"/>

บนเป้าหมายให้เพิ่มตัวแปร classpath เช่น .. , -DANT_HOME, -DJAVA_HOME

clean install -e -DPROJECT_HOME=..... -DANT_HOME=C:\bea1036\modules\org.apache.ant_1.7.1 -DJAVA_HOME=C:\bea1036\jdk160_31

1
คลาสพา ธ และใบรับรองไม่มีส่วนเกี่ยวข้องใด ๆ
มาร์ควิสแห่ง Lorne

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