it-swarm.asia

حل javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: فشل بناء مسار PKIX خطأ؟

تحرير: - حاول تنسيق السؤال والإجابة المقبولة بطريقة أكثر ملاءمة في منجممدونة

هنا هي القضية الأصلية.

سأتعامل مع هذا الخطأ:

رسالة مفصلة Sun.security.validator.ValidatorException: فشل بناء مسار PKIX:
Sun.security.provider.certpath.SunCertPathBuilderException: غير قادر على العثور على مسار شهادة صالح إلى الهدف المطلوب

تسبب javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: فشل بناء مسار PKIX: Sun.security.provider.certpath.SunCertPathBuilderException: غير قادر على العثور على مسار شهادة صالح إلى الهدف المطلوب

أنا أستخدم Tomcat 6 كملقم ويب. لديّ تطبيقان على شبكة HTTPS مثبتان على Tomcats مختلفين على منافذ مختلفة ولكن على نفس الجهاز. قل App1(port 8443) و App2(port 443). App1 يتصل بـ App2. عندما يتصل App1 بـ App2 أحصل على الخطأ أعلاه. أعرف أن هذا خطأ شائع جدًا ، لذا فقد واجهت العديد من الحلول في المنتديات والمواقع المختلفة. لدي الإدخال التالي في server.xml لكلا Tomcats:

keystoreFile="c:/.keystore" 
keystorePass="changeit"

يقول كل موقع نفس السبب في أن الشهادة المقدمة من app2 ليست في المتجر الموثوق به لـ app1 jvm. يبدو هذا صحيحًا أيضًا عندما حاولت الوصول إلى نفس عنوان URL في متصفح IE ، إنه يعمل (مع ارتفاع درجات الحرارة ، هناك مشكلة في شهادة أمان موقع الويب هذا ، وأقول هنا تابع إلى هذا الموقع). ولكن عندما يتم ضرب URL نفسه بواسطة عميل Java (في حالتي) ، تظهر لي الخطأ أعلاه. لذلك لوضعها في truststore جربت هذه الخيارات الثلاثة:

الخيار 1

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Option2 الإعداد أدناه في متغير البيئة

CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

Option3 الإعداد أدناه في متغير البيئة

Java_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

ولكن لا شيء يعمل .

ما الذي حدث أخيرًا يتم تنفيذ منهج Java المقترح في كيفية التعامل مع شهادات SSL غير الصالحة باستخدام Apache HttpClient؟ بواسطة Pascal Thivent ، أي تنفيذ برنامج InstallCert.

ولكن هذا النهج جيد لإعداد devbox لكن لا يمكنني استخدامه في بيئة الإنتاج.

أتساءل لماذا لم تنجح الطرق الثلاثة المذكورة أعلاه عندما ذكرت نفس القيم في server.xml لخادم app2 ونفس القيم في truststore عن طريق إعداد

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

في app1 البرنامج.

لمزيد من المعلومات ، هذه هي الطريقة التي أجري بها الاتصال:

URL url = new URL(urlStr);

URLConnection conn = url.openConnection();

if (conn instanceof HttpsURLConnection) {

  HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();

  conn1.setHostnameVerifier(new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
      return true;
    }
  });

  reply.load(conn1.getInputStream());
349
M Sach

تحتاج إلى إضافة الشهادة لـ App2 إلى ملف truststore الخاص بـ JVM المستخدم الموجود في %Java_HOME%\lib\security\cacerts.

أولاً ، يمكنك التحقق مما إذا كانت شهادتك موجودة بالفعل في متجر truststore من خلال تشغيل الأمر التالي: keytool -list -keystore "%Java_HOME%/jre/lib/security/cacerts" (لست بحاجة إلى تقديم كلمة مرور)

إذا كانت شهادتك مفقودة ، فيمكنك الحصول عليها عن طريق تنزيلها مع متصفحك وإضافتها إلى موقع truststore باستخدام الأمر التالي:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>

بعد الاستيراد ، يمكنك تشغيل الأمر الأول مرة أخرى للتحقق من إضافة شهادتك.

الشمس/معلومات أوراكل يمكن العثور عليها هنا .

344
SimonSez

javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: فشل بناء مسار PKIX: Sun.security.provider.certpath.SunCertPathBuilderException: غير قادر على العثور على مسار شهادة صالح إلى الهدف المطلوب

• عندما تلقيت الخطأ ، حاولت أن أحذف Google معنى التعبير ووجدت أن هذه المشكلة تحدث عندما يغيّر خادم شهادة HTTPS SSL ، ولا يتعرف إصدارنا الأقدم من Java على المرجع المصدق للشهادة (CA) .

• إذا كان بإمكانك الوصول إلى عنوان URL HTTPS في متصفحك ، فمن الممكن تحديث Java للتعرف على المرجع المصدق الجذر.

• في المستعرض الخاص بك ، انتقل إلى عنوان URL HTTPS الذي تعذر على Java الوصول إليه. انقر فوق سلسلة شهادات HTTPS (يوجد رمز قفل في Internet Explorer) ، انقر فوق القفل لعرض الشهادة.

• انتقل إلى "تفاصيل" الشهادة و "نسخ إلى ملف". انسخه في Base64 (.cer) التنسيق. سيتم حفظه على سطح المكتب الخاص بك.

• تثبيت الشهادة تجاهل جميع التنبيهات.

• هذه هي الطريقة التي جمعت بها معلومات الشهادة الخاصة بعنوان URL الذي كنت أحاول الوصول إليه.

الآن اضطررت إلى إنشاء إصدار Java الخاص بي لمعرفة الشهادة حتى لا يرفض التعرف على عنوان URL. في هذا الصدد ، يجب أن أذكر أنني خرجت من معلومات شهادة الجذر هذه بشكل افتراضي في JDK’s\jre\lib\security الموقع ، وكلمة المرور الافتراضية للوصول هي: changeit.

لعرض معلومات cacerts فيما يلي الإجراءات الواجب اتباعها:

• انقر فوق زر ابدأ -> تشغيل

• اكتب كمد. يتم فتح موجه الأوامر (قد تحتاج إلى فتحه كمسؤول).

• انتقل إلى دليل Java/jreX/bin الخاص بك

• اكتب ما يلي

keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts

أنه يعطي قائمة الشهادات الحالية الموجودة داخل لوحة المفاتيح. يبدو شيء مثل هذا:

C:\Documents and Settings\NeelanjanaG> keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts

أدخل كلمة السر الرئيسية: changeit

نوع المفتاح: jks

موفر المفاتيح: أحد

يحتوي مفتاحك على 44 مُدخلاً

verisignclass3g2ca ، 26 مارس 2004 ، TrustedCertEntry ،

بصمة الشهادة (MD5): A2: 33: 9B: 4C: 74: 78: 73: D4: 6C: E7: C1: F3: 8D: CB: 5C: E9

entrustclientca ، ٩ يناير ٢٠٠٣ ، TrustedCertEntry ،

بصمة الشهادة (MD5): 0C: 41: 2F: 13: 5B: A0: 54: F5: 96: 66: 2D: 7E: CD: 0E: 03: F4

thawtepersonalbasicca ، 13 فبراير 1999 ، TrustedCertEntry ،

بصمة الشهادة (MD5): E6: 0B: D2: C9: CA: 2D: 88: DB: 1A: 71: 0E: 4B: 78: EB: 02: 41

addtrustclass1ca ، 1 مايو ، 2006 ، TrustedCertEntry ،

بصمة الشهادة (MD5): 1E: 42: 95: 02: 33: 92: 6B: B9: 5F: C0: 7F: DA: D6: B2: 4B: FC

verisignclass2g3ca ، 26 مارس 2004 ، TrustedCertEntry ،

بصمة الشهادة (MD5): F8: BE: C4: 63: 22: C9: A8: 46: 74: 8B: B8: 1D: 1E: 4A: 2B: F6

• الآن اضطررت إلى تضمين الشهادة المثبتة مسبقًا في cacerts.

• فيما يلي الإجراء:

keytool –import –noprompt –trustcacerts -alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

إذا كنت تستخدم Java 7:

keytool –importcert –trustcacerts -alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE - changeorestit

• سيقوم بعد ذلك بإضافة معلومات الشهادة إلى ملف cacert.

هذا هو الحل الذي وجدته للاستثناء المذكور أعلاه !!

159
NDeveloper

كيفية العمل عليه في Tomcat 7

كنت أرغب في دعم شهادة موقعة ذاتيًا في تطبيق Tomcat ولكن فشل القصاصة التالية في العمل

import Java.io.DataOutputStream;
import Java.net.HttpURLConnection;
import Java.net.URL;

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

        URL url = new URL("https:// ... .com");
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        httpURLConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());

        String serializedMessage = "{}";
        wr.writeBytes(serializedMessage);
        wr.flush();
        wr.close();

        int responseCode = httpURLConnection.getResponseCode();
        System.out.println(responseCode);
    }
}

هذا هو ما حل مشكلتي:

1) قم بتنزيل الملف .crt

echo -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt
  • استبدل <your domain> بنطاقك (على سبيل المثال ، jossef.com)

2) قم بتطبيق ملف .crt في متجر شهادات cacerts الخاص بجافا

keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <Java HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
  • استبدل <your domain> بنطاقك (على سبيل المثال ، jossef.com)
  • استبدل <Java HOME> بدليل Java الرئيسي

3) اختراقه

على الرغم من أن iv'e قد قمت بتثبيت شهادتي في مخازن الشهادات الافتراضية Java ، يتجاهل Tomcat ذلك (يبدو أنه لم تتم تهيئته لاستخدام مخازن شهادات Java الافتراضية).

لاختراق هذا ، أضف ما يلي في مكان ما في الكود:

String certificatesTrustStorePath = "<Java HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);

// ...
30
Jossef Harush

في حالتي ، كانت المشكلة هي أن خادم الويب كان يرسل الشهادة فقط و المرجع المصدق الوسيط ، وليس المرجع المصدق الجذر. إضافة خيار JVM هذا حل المشكلة: -Dcom.Sun.security.enableAIAcaIssuers=true

يتوفر دعم لطريقة وصول caIssuers لملحق وصول معلومات السلطة. يتم تعطيله افتراضيًا للتوافق ويمكن تمكينه عن طريق تعيين خاصية النظام com.Sun.security.enableAIAcaIssuers إلى القيمة الحقيقية.

إذا تم التعيين على true ، فإن تطبيق PKIX الخاص بـ Sun's لـ CertPathBuilder يستخدم المعلومات في ملحق AIA الخاص بالشهادة (بالإضافة إلى CertStores المحددة) للعثور على شهادة المرجع المصدق المصدرة ، شريطة أن يكون URI من النوع ldap أو http أو ftp.

المصدر

6
Guillaume

ملف cacerts الخاص بي كان فارغًا تمامًا. لقد قمت بحل هذا عن طريق نسخ ملف cacerts من جهاز windows الخاص بي (والذي يستخدم Oracle Java 7) وقمت بمراقبته إلى صندوق Linux الخاص بي (OpenJDK).

cd %Java_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp

ثم على آلة لينكس

cp /tmp/cacerts /etc/ssl/certs/Java/cacerts

إنه عمل رائع حتى الآن.

5
Ryan Shillington

سبب آخر يمكن أن يكون إصدار قديم من JDK. كنت تستخدم jdk الإصدار 1.8.0_60 ، مجرد تحديث إلى أحدث إصدار حل مشكلة الشهادة.

5
Ali Ismayilov

باستخدام Tomcat 7 في نظام Linux ، فعلت هذه الحيلة.

String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

ضمن Linux ، لا يتم دائمًا إعداد $Java_HOME ، لكن عادةً /etc/alternatives/jre يشير إلى $Java_HOME/jre

4
Cedric Simon

بالنسبة لي ، ظهر هذا الخطأ أيضًا أثناء محاولة الاتصال بعملية وراء وكيل NGINX العكسي الذي كان يتعامل مع SSL.

اتضح أن المشكلة كانت شهادة بدون سلسلة الشهادة بأكملها متسلسلة. عندما أضفت certs المتوسطة ، تم حل المشكلة.

أتمنى أن يساعدك هذا.

4
YaDa

كنت أستخدم jdk1.8.0_171 عندما واجهت نفس المشكلة. جربت أفضل الحلول 2 هنا (إضافة شهادة باستخدام keytool والحل الآخر الذي يحتوي على اختراق) ، لكنهم لم يعملوا من أجلي.

لقد قمت بترقية JDK إلى 1.8.0_181 وكان يعمل مثل السحر.

4
avp

أدناه رمز يعمل بالنسبة لي:

import Java.security.cert.CertificateException;
import Java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class TrustAnyTrustManager implements X509TrustManager {

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

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}

HttpsURLConnection conn = null;
            URL url = new URL(serviceUrl);
            conn = (HttpsURLConnection) url.openConnection();
             SSLContext sc = SSLContext.getInstance("SSL");  
             sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new Java.security.SecureRandom());  

             conn.setSSLSocketFactory(sc.getSocketFactory());
4
Sandip S.

كتبت برنامج نصي صغير Win32 (WinXP 32bit testet) غبي كمد (سطر الأوامر) الذي يبحث عن جميع إصدارات جافا في ملفات البرنامج ويضيف سيرت لهم. يجب أن تكون كلمة المرور هي "changeit" الافتراضي أو قم بتغييرها بنفسك في البرنامج النصي :-)

@echo off

for /F  %%d in ('dir /B %ProgramFiles%\Java') do (
    %ProgramFiles%\Java\%%d\bin\keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%\Java\%%d\lib\security\cacerts -storepass changeit
)

pause
2
mons droid

لتشغيل Tomcat على خادم Ubuntu ، لمعرفة أي Java قيد الاستخدام ، استخدم أمر "ps -ef | grep Tomcat":

عينة:

/home/mcp01$ **ps -ef |grep Tomcat**
Tomcat7  28477     1  0 10:59 ?        00:00:18 **/usr/local/Java/jdk1.7.0_15/bin/Java** -Djava.util.logging.config.file=/var/lib/Tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.Apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/Tomcat7/endorsed -classpath /usr/share/Tomcat7/bin/bootstrap.jar:/usr/share/Tomcat7/bin/Tomcat-juli.jar -Dcatalina.base=/var/lib/Tomcat7 -Dcatalina.home=/usr/share/Tomcat7 -Djava.io.tmpdir=/tmp/Tomcat7-Tomcat7-tmp org.Apache.catalina.startup.Bootstrap start
1005     28567 28131  0 11:34 pts/1    00:00:00 grep --color=auto Tomcat

بعد ذلك ، يمكننا الدخول إلى: cd /usr/local/Java/jdk1.7.0_15/jre/lib/security

الافتراضي cacerts الملف موجود هنا. أدخل الشهادة غير الموثوق بها.

1
oraclesoon

انا أيضا لدي هذه المشكلة.

جربت كل شيء تقريبًا عن طريق إضافة شهادة SSL إلى .keystore ، لكن لم تكن تعمل مع Java1_6_x. بالنسبة لي ، لقد ساعدنا ذلك إذا بدأنا في استخدام الإصدار الأحدث من Java ، Java1_8_x كـ JVM.

0
Nubian

بالنسبة لنظام التشغيل MacOS X أدناه ، تم تنفيذ الأمر الدقيق لي حيث اضطررت لمحاولة استخدام الواصلة المزدوجة في خيار "importcert" الذي نجح:

Sudo keytool -–importcert -file /PathTo/YourCertFileDownloadedFromBrowserLockIcon.crt -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/security/cacerts -alias "Cert" -storepass changeit
0
apandey846

من أجل السلامة ، يجب ألا نستخدم الشهادات الموقعة ذاتيا في تطبيقنا. ومع ذلك ، عندما يتعلق الأمر بالتطوير في كثير من الأحيان ، يتعين علينا استخدام البيئات التجريبية التي حصلت على توقيعات ذاتية. حاولت إصلاح هذه المشكلة برمجيًا في الكود وفشلت. ومع ذلك ، من خلال إضافة cert إلى jre trust-store ، حل مشكلتي. تجدون أدناه الخطوات ،

  1. تحميل الموقع سيرت ،

  2. انسخ الشهادة (على سبيل المثال: cert_file.cer) إلى الدليل $ Java_HOME\Jre\Lib\Security

  3. افتح CMD في المسؤول وقم بتغيير الدليل إلى $ Java_HOME\Jre\Lib\Security

  4. استيراد الشهادة إلى متجر موثوق باستخدام الأمر أدناه ،

keytool -import -alias ca -file cert_file.cer -cystations cacerts -storepass changeit

(إذا حصلت على خطأ يقول أن أداة المفاتيح غير معروفة ، فيرجى راجع هذا.

اكتب نعم مثل أدناه

الوثوق بهذه الشهادة: [نعم]

  1. حاول الآن تشغيل التعليمات البرمجية الخاصة بك أو الوصول إلى URL برمجيًا باستخدام Java.

تحديث

إذا كان خادم التطبيق الخاص بك هو jboss ، فجرّب إضافة خاصية النظام أدناه

System.setProperty("org.jboss.security.ignoreHttpsHost","true");

أتمنى أن يساعدك هذا!

0
tk_

واجهت هذه المشكلة باستخدام AndroidStudio و Charles Proxy و JUnit و Robolectric. شكراSimonSez يمكنني حل المشكلة.

  1. %Java_HOME% - يستخدم Android JavaHome مختلفًا. يمكنك العثور على المسار الكامل في نافذة RunUnitTests. في حالتي ، /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
  2. قم بتنزيل شهادة Charles في مجلد Downloads
  3. قم بتشغيل الأمر

    Sudo keytool -import -noprompt -trustcacerts -alias charles -file ~/Downloads/charles-ssl-proxying-certificate.pem -keystore "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/security/cacerts" -storepass changeit

وثيقة تشارلز الرسمية

0
yoAlex5