javax.net.ssl.SSLHandshakeException 해결 : sun.security.validator.ValidatorException : PKIX 경로 빌드 실패 오류?


426

편집 :- 내 블로그 에서 질문을 더 표현 가능한 방식으로 형식화하려고 시도했습니다.

원래 문제는 다음과 같습니다.

이 오류가 발생합니다.

자세한 메시지 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을 웹 서버로 사용하고 있습니다. 다른 포트의 다른 Tomcat에 동일한 시스템에 두 개의 HTTPS 웹 응용 프로그램이 설치되어 있습니다. 말 App1(port 8443)과 App2(port 443). App1에 연결합니다 App2. 에 App1연결할 때 App2위의 오류가 발생합니다. 나는 이것이 매우 일반적인 오류이므로 다른 포럼과 사이트의 많은 솔루션을 발견했습니다. server.xml두 Tomcat 에 아래 항목이 있습니다 .

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

모든 사이트는 app2가 제공 한 인증서가 app1 jvm의 신뢰할 수있는 저장소에없는 것과 같은 이유를 말합니다. IE 브라우저에서 동일한 URL을 누르려고 할 때도 마찬가지입니다.이 웹 사이트의 보안 인증서에 문제가 있습니다.이 웹 사이트를 계속 진행하십시오. 그러나 동일한 URL이 Java 클라이언트 (내 경우)에 충돌하면 위의 오류가 발생합니다. 그래서 그것을 신뢰 저장소에 넣으려면 다음 세 가지 옵션을 시도했습니다.

옵션 1

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

옵션 2 환경 변수에서 아래 설정

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

옵션 3 환경 변수에서 아래 설정

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

그러나 아무것도 효과가 없었습니다 .

마지막 으로 Apache HttpClient로 유효하지 않은 SSL 인증서를 처리하는 방법에서 제안 된 Java 접근 방식을 실행하고 있습니까? Pascal Thivent에 의해, 즉 InstallCert 프로그램을 실행합니다.

그러나이 방법은 devbox 설정에는 적합하지만 프로덕션 환경에서는 사용할 수 없습니다.

나는 동일한 값을 언급 할 때 세 가지 방법은 위의 일을하지 않았다 언급 왜 궁금 server.xml의 app2설정에 의해 신뢰 저장소에 서버와 같은 값

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


SSL 문제가없는 클러스터 된 서버간에 통신 할 때이 오류가 발생했습니다. domainnameRHEL 서버에 올바르게 설정 하면 문제가 사라졌습니다. 그것이 누군가를 돕기를 바랍니다.
— DavidG

확인해야 할 또 다른 사항은 최신 버전의 Java가 있다는 것입니다.이 때문에 비슷한 오류가 발생했습니다.
— Redzarf

stackoverflow.com/questions/2893819/…- 관련성과 환상적인 답변.
— Siddhartha

답변:


406

에 위치한 사용 된 JVM의 신뢰 저장소 파일에 App2 에 대한 인증서를 추가해야합니다 %JAVA_HOME%\lib\security\cacerts.

먼저 다음 명령을 실행하여 인증서가 이미 신뢰 저장소에 있는지 확인할 수 있습니다. keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"(비밀번호를 제공 할 필요가 없습니다)

인증서가 누락 된 경우 브라우저로 인증서를 다운로드하여 얻을 수 있으며 다음 명령을 사용하여 신뢰 저장소에 추가하십시오.

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

가져온 후 첫 번째 명령을 다시 실행하여 인증서가 추가되었는지 확인할 수 있습니다.

Sun / Oracle 정보는 여기를 참조하십시오 .


6
c : \ java \ jdk \ lib \ security \ cacerts와 같은 전체 경로를 사용해야합니다.
— SimonSez

48
SimonSez가 말했듯이 암호는 필요하지 않지만 원하는 경우 기본 암호는 "changeit"입니다.
— Felix

16
또한 Windows에서는 터미널을 관리자로 실행해야합니다. 그렇지 않으면 keytool error: java.io.FileNotFoundException ... (Access is denied)인증서를 가져 오려고 할 때 오류가 발생합니다.
— Felix

2
아 @SimonSez 당신은 나의 신입니다. 그러나이를 추가하려면 @M Sach가 언급 한대로 신뢰 저장소 위치 및 비밀번호를 지정해야 작동합니다.
— BudsNanKis

2
Java 1.8에 계속 문제가 있습니다. 설명 된대로 인증서를 추가하고 Java <1.8을 사용해야 함
— Tom Howard

180

javax.net.ssl.SSLHandshakeException : sun.security.validator.ValidatorException : PKIX 경로 작성 실패 : sun.security.provider.certpath.SunCertPathBuilderException : 요청 된 대상에 대한 유효한 인증 경로를 찾을 수 없습니다.

• 오류가 발생했을 때 Google에서 표현식의 의미를 알아 내려고했지만 서버에서 HTTPS SSL 인증서를 변경하고 이전 버전의 java가 루트 인증 기관 (CA)을 인식하지 못하는 경우이 문제가 발생합니다. .

• 브라우저에서 HTTPS URL에 액세스 할 수 있으면 루트 CA를 인식하도록 Java를 업데이트 할 수 있습니다.

• 브라우저에서 Java가 액세스 할 수없는 HTTPS URL로 이동하십시오. HTTPS 인증서 체인 (Internet Explorer에 잠금 아이콘이 있음)을 클릭하고 잠금을 클릭하여 인증서를보십시오.

• 인증서의 "세부 사항"및 "파일로 복사"로 이동하십시오. Base64 (.cer) 형식으로 복사하십시오 . 데스크탑에 저장됩니다.

• 모든 경고를 무시하고 인증서를 설치하십시오.

• 액세스하려는 URL의 인증서 정보를 수집 한 방법입니다.

이제 인증서에 대해 알 수 있도록 Java 버전을 만들어야 URL이 더 이상 인식되지 않습니다. 이와 관련하여 루트 인증서 정보가 기본적으로 JDK의 \ jre \ lib \ security 위치에 유지되며 액세스 할 기본 비밀번호는 changeit입니다.

cacerts 정보를 보려면 다음 절차를 따르십시오.

• 시작 버튼-> 실행을 클릭하십시오.

• cmd를 입력하십시오. 명령 프롬프트가 열립니다 (관리자로 열어야 할 수도 있음).

• 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

키 스토어 제공 업체 : SUN

키 저장소에 44 개의 항목이 있습니다.

verisignclass3g2ca, 2004 년 3 월 26 일, trustedCertEntry,

인증서 지문 (MD5) : A2 : 33 : 9B : 4C : 74 : 78 : 73 : D4 : 6C : E7 : C1 : F3 : 8D : CB : 5C : E9

entrustclientca, 2003 년 1 월 9 일, trustedCertEntry,

인증서 지문 (MD5) : 0C : 41 : 2F : 13 : 5B : A0 : 54 : F5 : 96 : 66 : 2D : 7E : CD : 0E : 03 : F4

thawtepersonalbasicca, 1999 년 2 월 13 일, trustedCertEntry,

인증서 지문 (MD5) : E6 : 0B : D2 : C9 : CA : 2D : 88 : DB : 1A : 71 : 0E : 4B : 78 : EB : 02 : 41

addtrustclass1ca, 2006 년 5 월 1 일, trustedCertEntry,

인증서 지문 (MD5) : 1E : 42 : 95 : 02 : 33 : 92 : 6B : B9 : 5F : C0 : 7F : DA : D6 : B2 : 4B : FC

verisignclass2g3ca, 2004 년 3 월 26 일, trustedCertEntry,

인증서 지문 (MD5) : F8 : BE : C4 : 63 : 22 : C9 : A8 : 46 : 74 : 8B : B8 : 1D : 1E : 4A : 2B : F6

• 이제 이전에 설치된 인증서를 cacert에 포함시켜야했습니다.

•이를위한 절차는 다음과 같습니다.

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

Java 7을 사용중인 경우 :

keytool –importcert –trustcacerts –alias ALIASNAME-파일 PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

그런 다음 인증서 정보를 cacert 파일에 추가합니다.

위에서 언급 한 예외에 대해 찾은 솔루션입니다!


5
인증서가 만료되면 어떻게합니까? 모든 것을 반복합니까 (연간)?
— ggkmath

7
프로그래밍 방식 으로이 작업을 수행 할 수있는 방법이 있습니까?
— Meshulam Silk

1
"경로가 트러스트 앵커와 연결되지 않습니다"라는 PKIX 오류를 다루는 사람들에게이 솔루션은 불행히도 그 문제를 해결하지 못했습니다.
— IcedDante

3
한 가지 질문-aliasName은 인증서를 가져 오는 웹 주소입니까? 예를 들어 URL이 domain.site.com/pages/service.asmx 인 경우 별명은 domain.site.com 또는 완전한 URL (domain.site.com/pages/service.asmx)이거나 http로 시작해야합니다. 또는 임의의 이름입니까?
— nanosoft

1
path : \ lib \ security> keytool -import -noprompt -trustcacerts -alias webCert -file webCertResource.cer -keystore c : / Users / Jackie / Desktop -storepass changeit "시스템이 지정된 파일을 찾을 수 없습니다"
— Jesse

46

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파일을 Java 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>자바 홈 디렉토리로 교체

3) 해킹

iv Java는 기본 인증서 저장소에 인증서를 설치했지만 Tomcat은이를 무시합니다 (Java의 기본 인증서 저장소를 사용하도록 구성되지 않은 것으로 보입니다).

이것을 해킹하려면 코드 어딘가에 다음을 추가하십시오.

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

// ...

4
2 단계는 SpringBoot 및 Tomcat 7을 사용하여 트릭을 수행했습니다. 감사합니다.
— Tim Perry

? 나는 하나 개의 서버에 나는 많은 자바를 가질 수 있기 때문에 바람둥이에 의해 사용되는 자바에서 키 도구를 사용해야합니까
— vikifor

@vikifor 네. 또한 시스템에 설치된 모든 Java 디렉토리에 대해 실행할 수 있습니다
— Jossef Harush

1
이것은 효과가 있었다! 유용한 답변에 대해 @JossefHarush에게 감사드립니다!
— Tom Taylor

1
@Jossef Harush의 코드 세그먼트를 코드에 추가 한 후 내 문제가 해결되었습니다.
— Chamod Pathirana

10

필자의 경우 문제는 웹 서버가 루트 CA가 아닌 인증서와 중간 CA 만 보내는 것입니다. 이 JVM 옵션을 추가하면 문제가 해결되었습니다.-Dcom.sun.security.enableAIAcaIssuers=true

기관 정보 액세스 확장의 CaIssuers 액세스 방법에 대한 지원이 제공됩니다. 호환성을 위해 기본적으로 비활성화되어 있으며 시스템 속성 com.sun.security.enableAIAcaIssuers을 true 로 설정하여 활성화 할 수 있습니다 .

true로 설정하면 Sun의 CertPathBuilder PKIX 구현은 인증서의 AIA 확장 (지정된 CertStores와 함께)의 정보를 사용하여 발급 CA 인증서를 찾습니다 (ldap, http 또는 ftp 유형의 URI 인 경우).

출처


이것은 실제로 내 문제를 해결했습니다. 감사합니다!
— Luís Silva가

6

또 다른 이유는 JDK의 오래된 버전 일 수 있습니다. jdk 버전 1.8.0_60을 사용하고 있었고 최신 버전으로 업데이트하면 인증서 문제가 해결되었습니다.


2
나도 같은 문제가 있었다. Lets Encrypt Certificate를 사용하여 API를 호출하면 신뢰할 수있는 루트 인증 기관에서 인식하지 못하므로 이전 버전의 Java에서는 작동하지 않을 수 있습니다. Java를 업데이트하면이 문제가 해결됩니다.
— hertg

5

내 cacerts 파일이 완전히 비어있었습니다. cacerts 파일을 Windows 시스템 (Oracle Java 7을 사용하는)에서 복사하여 Linux 상자 (OpenJDK)에 scp했습니다.

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

그리고 리눅스 머신에서

cp /tmp/cacerts /etc/ssl/certs/java/cacerts

지금까지 훌륭하게 작동했습니다.


1
문제가 최신 인증서가없는 이전 버전의 Java를 사용하고 있다면 훌륭하게 작동합니다.
— atripathi

@ atripathi Mac은 어떻습니까?
— iOSAndroidWindowsMobileAppsDev

cacerts 파일이 비어 있으면 Java 설치에 심각한 문제가 있습니다. 모두 다시 설치해야합니다.
— Lorne의 후작

아마도, 그러나이 솔루션은 효과가 있었고 이후에는 아무것도 잘못되지 않았습니다.
— Ryan Shillington

5

나 에게이 오류는 SSL을 처리하는 NGINX 리버스 프록시 뒤의 프로세스에 연결하려고 할 때도 나타납니다.

문제는 전체 인증서 체인이 연결되지 않은 인증서라는 것이 밝혀졌습니다. 중간 인증서를 추가하면 문제가 해결되었습니다.

도움이 되었기를 바랍니다.


그게 내가 가지고있는 것처럼 보입니다. 중간 인증서를 추가 한 방법과 위치에 대해 설명 할 수 있습니다. im은 NGINX가 아닌 httpd revers 프록시를 사용합니다.
— Asaf Magen 2019

이것은 내 경우에 httpd : access.redhat.com/solutions/43575를
— Asaf Magen

nginx에서는 SSL 구성에 .key 및 .pem 파일 만 사용합니다. 먼저 .crt를 .pem (단순 : cp yourfile.crt yourfile.pem)으로 변환 한 다음 SSL 인증서 체인의 경우 .cer 파일을 .pem의 마지막에 추가하십시오 (cat yourfile.cer >> yourfile.pem)
— Thế Anh Nguyễn

5

Linux에서 Tomcat 7을 사용하여 트릭을 수행했습니다.

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


5

아래 코드는 저에게 효과적입니다.

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

5
이 코드는 완전히 안전하지 않으므로 사용해서는 안됩니다.
— Lorne의 후작

왜 안전하지 않습니까? 코드에서 간단하게 발생하는 일.
— Govinda Sakhare

이것은 모든 인증서 유효성 검사를 건너 뛰고 기본적으로 모든 인증서를 허용합니다. 인증서가 작동하는 방식은 다양한 인증 기관에 물리적으로 보호되는 루트 인증서가 있다는 것입니다. 그런 다음이 인증서는 다른 2 차 인증서를 발급하는 데 사용되며 루트 인증 기관으로 다시 확인할 수 있습니다. 이것은 모든 업스트림 검사를 건너 뜁니다. 즉, 모든 SSL 인증서 (자체 생성)를 보낼 수 있으며 URL로 내 신원이 확인되지 않아도 응용 프로그램에서 보안으로 수락합니다.
— Scott Taylor

4

나는 jdk1.8.0_171같은 문제에 직면했을 때 사용하고있었습니다 . 여기서 2 가지 솔루션 (keytool을 사용하여 인증서 추가 및 해킹이있는 다른 솔루션 추가)을 시도했지만 나에게 도움이되지 않았습니다.

JDK를 업그레이드 1.8.0_181했으며 매력처럼 작동했습니다.


2

프로그램 파일에서 모든 Java 버전을 찾아서 인증서를 추가하는 작은 win32 (WinXP 32bit testet) 바보 cmd (명령 줄) 스크립트를 작성했습니다. 비밀번호는 기본 "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

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

2

나를 위해 https://stackoverflow.com/a/9619478/4507034 이 게시물에서 인식 된 해결책을 찾지 못했습니다 .

대신 인증을 내 컴퓨터의 신뢰할 수있는 인증으로 가져 와서 문제를 해결했습니다.

단계 :

  1. https://localhost:8443/yourpath인증이 작동하지 않는 URL (예 :)로 이동하십시오 .
  2. 언급 된 게시물에 설명 된대로 인증을 내 보냅니다.
  3. Windows 컴퓨터에서 다음을 엽니 다. Manage computer certificates
  4. Trusted Root Certification Authorities->로 이동Certificates
  5. 여기에서 your_certification_name.cer파일을 가져 오십시오 .

1

Ubuntu 서버에서 실행중인 Tomcat의 경우 사용중인 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

안전을 위해 구현시 자체 서명 된 인증서를 사용해서는 안됩니다. 그러나 개발과 관련하여 종종 자체 서명 인증서를 얻은 시험 환경을 사용해야합니다. 내 코드에서 프로그래밍 방식 으로이 문제를 해결하려고했지만 실패합니다. 그러나 인증서를 jre trust-store에 추가하면 문제가 해결되었습니다. 아래 단계를 찾으십시오.

  1. 사이트 인증서를 다운로드하십시오.

  2. 인증서 (ex : cert_file.cer)를 $ JAVA_HOME \ Jre \ Lib \ Security 디렉토리에 복사하십시오.

  3. 관리자에서 CMD를 열고 디렉토리를 $ JAVA_HOME \ Jre \ Lib \ Security로 변경하십시오.

  4. 아래 명령을 사용하여 인증서를 신뢰 저장소로 가져 오십시오.

keytool -import-별칭 ca -file cert_file.cer -keystore cacerts -storepass changeit

keytool을 인식 할 수 없다는 오류가 발생하면이를 참조하십시오.

아래와 같이 yes를 입력하십시오

이 인증서를 신뢰하십시오. [예]

  1. 이제 코드를 실행하거나 java를 사용하여 프로그래밍 방식으로 URL에 액세스하십시오.

최신 정보

앱 서버가 jboss 인 경우 시스템 속성 아래에 추가하십시오.

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

도움이 되었기를 바랍니다!


1

배포 가능한 솔루션 (Alpine Linux)

애플리케이션 환경에서이 문제를 해결하기 위해 다음과 같이 Linux 터미널 명령을 준비했습니다.

cd ~

홈 디렉토리에 인증서 파일을 생성합니다.

apk add openssl

이 명령은 alpine Linux에 openssl을 설치합니다. 다른 Linux 배포판에 적합한 명령을 찾을 수 있습니다.

openssl s_client -connect <host-dns-ssl-belongs> < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt

필요한 인증서 파일을 생성했습니다.

sudo $JAVA_HOME/bin/keytool -import -alias server_name -keystore $JAVA_HOME/lib/security/cacerts -file public.crt -storepass changeit -noprompt

프로그램 'keytool'을 사용하여 생성 된 파일을 JRE에 적용했습니다.

참고 : DNS를<host-dns-ssl-belongs>

참고 2 :-noprompt 확인 메시지를 표시하지 않고 (yes / no) -storepass changeit매개 변수는 암호 프롬프트를 비활성화하고 필요한 암호를 제공합니다 (기본값은 'changeit'). 이 두 속성을 사용하면 Docker 이미지 빌드와 같은 응용 프로그램 환경에서 해당 스크립트를 사용할 수 있습니다.

참고 3 Docker를 통해 앱을 배포하는 경우 비밀 파일을 한 번 생성하여 애플리케이션 프로젝트 파일에 넣을 수 있습니다. 반복해서 생성 할 필요가 없습니다.


0

이 문제도 있습니다.

SSL 인증서를 .keystore에 추가하여 거의 모든 것을 시도했지만 Java1_6_x에서는 작동하지 않았습니다. 나를 위해 최신 버전의 Java, Java1_8_x를 JVM으로 사용하기 시작했습니다.


1
저도 마찬가지입니다. Java 1.8.0_91에서 1.8.0_121로 업데이트하면 문제가 해결되었습니다. Apache HTTPClient를 사용하여 예외가 발생했습니다.
— Devabc

여전히 Oauth2 인증을 사용하여이 문제가 있습니다.
— Sofiane

0

프록시 뒤에있을 때 Android Studio 에서이 문제가 발생했습니다. 빌드 중에 매핑 파일을 업로드하려고하는 Crashlytics를 사용하고있었습니다.

누락 된 프록시 인증서를 다음 위치의 신뢰 저장소에 추가했습니다. /Users/[username]/Documents/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/security/cacerts

다음 명령으로 keytool -import -trustcacerts -keystore cacerts -storepass [password] -noprompt -alias [alias] -file [my_certificate_location]

예를 들어 기본 신뢰 저장소 비밀번호 keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias myproxycert -file /Users/myname/Downloads/MyProxy.crt


0

작은 해킹. "hudson.model.UpdateCenter.xml"파일의 URL을 https에서 http로 업데이트하십시오.

<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>http://updates.jenkins.io/update-center.json</url>
  </site>
</sites>

0

Java로 파일을 다운로드 해야하는 QEMU 환경이 있기 때문에 차임하고 싶습니다. /etc/ssl/certs/java/cacertsQEMU에서 일치하지 않기 때문에 문제가 있음 이 밝혀졌습니다 ./etc/ssl/certs/java/cacerts호스트 환경에서 . 호스트 환경은 회사 프록시 뒤에 있으므로 java cacerts는 사용자 정의 된 버전입니다.

QEMU 환경을 사용하는 경우 호스트 시스템이 먼저 파일에 액세스 할 수 있는지 확인하십시오. 예를 들어 호스트 컴퓨터 에서이 스크립트 를 먼저 사용해 볼 수 있습니다. QEMU가 아닌 호스트 시스템에서 스크립트가 제대로 실행되면 나와 같은 문제가있는 것입니다.

이 문제를 해결하기 위해 QEMU에서 원본 파일을 백업하고 호스트 환경의 파일을 QEMU chroot jail로 복사 한 다음 java가 QEMU에서 파일을 정상적으로 다운로드 할 수있었습니다.

더 나은 솔루션은 /etcQEMU 환경에 마운트하는 것 입니다. 그러나 다른 파일이이 프로세스에 영향을 미치는지 확실하지 않습니다. 그래서 나는이 추악하지만 쉬운 해결 방법을 사용하기로 결정했습니다.


0

이것은 악명 높은 PKIX 오류 메시지에 대한 다른 가능한 이유를 문서화하는 것만 큼 좋은 곳으로 보입니다. 키 저장소와 신뢰 저장소 내용과 다양한 Java 설치 구성을 너무 오래 보니 내 문제가 오타라는 것을 깨달았습니다.

오타는 키 저장소를 신뢰 저장소로 사용하고 있음을 의미했습니다. 내 회사 루트 CA는 키 저장소에서 독립 실행 형 인증서로 정의되지 않고 인증서 체인의 일부로 만 정의되었으며 다른 곳 (예 : cacerts)으로 정의되지 않았으므로 PKIX 오류가 계속 발생했습니다.

실패한 릴리스 (이것은 prod config, 다른 곳에서는 괜찮 았습니다)와 이틀간의 머리 긁음은 마침내 오타를 보았으며 이제는 모두 좋습니다.

이것이 누군가를 돕기를 바랍니다.


-1

이것을 코드에 추가하십시오 :

TrustManager[] trustAllCerts = new TrustManager[]{
           new X509TrustManager() {
               @Override
               public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                   return new X509Certificate[0];
               }

               @Override
               public void checkClientTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }

               @Override
               public void checkServerTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }
           }
       };

       try {
           SSLContext sc = SSLContext.getInstance("SSL");
           sc.init(null, trustAllCerts, new java.security.SecureRandom());
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
       } catch (GeneralSecurityException e) {
       }

1
코드 전용 답변은 일반적으로이 사이트에서 눈살을 찌푸립니다. 코드에 대한 주석이나 설명을 포함하도록 답변을 편집 해 주시겠습니까? 설명은 다음과 같은 질문에 답변해야합니다. 어떻게합니까? 어디로 갑니까? OP의 문제를 어떻게 해결합니까?
— mypetlion

1
코드에 이것을 추가 제 하지 코드에 이것을 추가 . 이러한 방식으로 SSLContext를 작성하면 연결중인 서버의 ID를 확인하는 모든 보안 검사가 제거됩니다. 열쇠를 잃어버린 문제에 대한 답은 자신이 소유 한 모든 것에서 모든 자물쇠를 제거하는 것이 아닙니다 .
— Andrew Henle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.