"java.security.cert.CertificateException : 제목 대체 이름 없음"오류를 수정하는 방법은 무엇입니까?


108

HTTPS를 통해 웹 서비스를 사용하는 Java 웹 서비스 클라이언트가 있습니다.

import javax.xml.ws.Service;

@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
    extends Service
{

    public ISomeService() {
        super(__getWsdlLocation(), ISOMESERVICE_QNAME);
    }

서비스 URL ( https://AAA.BBB.CCC.DDD:9443/ISomeService)에 연결할 때 예외가 발생 java.security.cert.CertificateException: No subject alternative names present합니다.

이 문제를 해결하기 위해 먼저 openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt파일을 실행 하고 다음 내용을 얻었습니다 certs.txt.

CONNECTED(00000003)
---
Certificate chain
 0 s:/CN=someSubdomain.someorganisation.com
   i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5            
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx:                 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    Start Time: 1382521838
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

AFAIK, 이제

  1. certs.txt사이 의 일부를 추출 -----BEGIN CERTIFICATE-----하고 -----END CERTIFICATE-----,
  2. 인증서 이름이 같도록 수정 AAA.BBB.CCC.DDD하고
  3. 그런 다음 keytool -importcert -file fileWithModifiedCertificate(여기서는 fileWithModifiedCertificate작업 1과 2 의 결과)를 사용하여 결과를 가져옵니다 .

이 올바른지?

그렇다면 IP 기반 주소 ( AAA.BBB.CCC.DDD) 에서 1 단계의 인증서를 정확히 어떻게 작동시킬 수 있습니까?

업데이트 1 (2013년 10월 23일 15시 37분 MSK는) : A와 답변에 비슷한 질문 , 나는 다음을 읽어

해당 서버를 제어하지 않는 경우 해당 호스트 이름을 사용합니다 (기존 인증서에 해당 호스트 이름과 일치하는 CN이 적어도있는 경우).

"사용"이란 정확히 무엇을 의미합니까?

답변:


153

여기에 제시된 접근 방식을 사용하여 HTTPS 검사를 비활성화하여 문제를 해결했습니다 .

ISomeService클래스 에 다음 코드를 넣었습니다 .

static {
    disableSslVerification();
}

private static void disableSslVerification() {
    try
    {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
}

https://AAA.BBB.CCC.DDD:9443/ISomeService테스트 목적으로 만 사용하고 있기 때문에 충분한 솔루션입니다.


위에서 언급 한 링크에 언급 된 접근 방식은 차단 된 것으로 보입니다 ( nakov.com/blog/2009/07/16/… ). 누구든지 링크를 업데이트 할 수 있습니까?
John

이 프로세스를 수행하여 유효성 검사를 비활성화하려고 시도했지만 SSL 프로토콜 (Poodle 취약점)에 대한 브라우저 유효성 검사는 ssl_error_no_cypher_overlap을 제공합니다. 어떤 아이디어?
will824

안녕하세요, org.springframework.web.client.HttpClientErrorException : 403 Forbidden

73
HTTPS 검사를 비활성화하는 것은 "해결책"이 아닙니다. 내가 "패치"를 찾았다 고 말해야합니다.
Jus12 2016 년

2
이로 인해 Pre_prod 및 Production에 취약성이 발생합니다. 1. Windows 호스트 파일에 호스트 항목을 만듭니다. 2. 또는 인증서의 제목 대체 이름 필드에 IP 또는 FQDN 이름을 추가합니다.
Shankar

34

나는 같은 문제를 가지고 있으며이 코드로 해결되었습니다. 웹 서비스를 처음 호출하기 전에이 코드를 넣었습니다.

javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

    public boolean verify(String hostname,
            javax.net.ssl.SSLSession sslSession) {
        return hostname.equals("localhost");
    }
});

간단하고 잘 작동합니다.

다음 은 원본입니다.


3
또는 return hostname.equals("localhost");원하는 경우 verify () 함수의 전체 본문을로 바꿀 수 있습니다 . 은 if완전히 불필요합니다.
CVn

이것은 적절한 인증서가없는 공급 업체의 테스트 환경에서 테스트 할 수있는 간단하고 빠른 수정이었습니다. 정말 감사합니다!
dacDave

나를 위해 일한 @ JuanM.Hidalgo는 위의 코드를 HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();. 또한 이것은 모든 인증서를 무시합니까? 그러한 해결 방법이 보안에 취약하다는 것을 알았 기 때문에. 감사합니다!
ThunderWiring

이 답변은 SSL 인증서 예외 및 LDH가 아닌 문자 문제를 해결했습니다. 오픈 JDK에서보고 된 버그가 있음을 알 수 있습니다. bugs.openjdk.java.net/browse/JDK-8170265
아킬 S Kamath

28

이것은 오래된 질문이지만 JDK 1.8.0_144에서 jdk 1.8.0_191로 이동할 때 동일한 문제가 발생했습니다.

변경 로그에서 힌트를 찾았습니다.

변경 로그

다음과 같은 추가 시스템 속성을 추가하여이 문제를 해결하는 데 도움이되었습니다.

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

25

클라이언트가 요청하는 내용에 대해 인증서 ID 확인이 수행됩니다.

클라이언트가 https://xxx.xxx.xxx.xxx/something(wherexxx.xxx.xxx.xxx IP 주소)를 사용할 때이 IP 주소에 대해 인증서 ID를 확인합니다 (이론상 IP SAN 확장 만 사용).

인증서에 IP SAN이 없지만 DNS SAN (또는 DNS SAN이없는 경우 주체 DN의 공통 이름)이있는 경우 클라이언트가 해당 호스트 이름 (또는 호스트 이름 가능한 값이 여러 개인 경우 인증서가 유효합니다). 예를 들어 cert에에 대한 이름이있는 www.example.com경우 https://www.example.com/something.

물론 해당 IP 주소로 확인하려면 해당 호스트 이름이 필요합니다.

또한 DNS SAN이있는 경우 주제 DN의 CN이 무시되므로이 경우 DNS SAN 중 하나와 일치하는 이름을 사용하십시오.


1
을 통해 서비스에 액세스 할 수 없습니다 http://www.example.com/someservice. 인증서가 IP 기반 주소 ( https://AAA.BBB.CCC.DDD:9443/ISomeService)에서 작동 하려면 모든 CN필드를 AAA.BBB.CCC.DDD( 위 파일에서로 대체) someSubdomain.someorganisation.com로 설정 AAA.BBB.CCC.DDD하고 결과 인증서 파일을 가져와야하는 것이 맞 습니까?
Mentiflectax 2013 년

서버를 제어하지 않는 경우 CN 또는 인증서에 대해 아무것도 할 수 없습니다.
Bruno

수정할 수있는 테스트 용 IP 주소에 대한 액세스 권한을 일시적으로 /etc/hosts파일 또는 동급
tyoc213

1
내 코드에서는 공용 IP로 요청을 보냈지 만 인증서 CN은 호스트 이름이었습니다. 그래서 내 코드에서 IP를 호스트 이름으로 바꾸고이 호스트 이름을 IP에 연결하도록 / etc / hosts를 구성했습니다. 해결!
Leopold Gault

15

인증서를 가져 오려면 :

  1. 서버에서 인증서를 추출합니다. 예를 들어 openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txtPEM 형식으로 인증서를 추출합니다.
  2. keytool이 예상하는 것과 같이 인증서를 DER 형식으로 변환하십시오. openssl x509 -in certs.txt -out certs.der -outform DER
  3. 이제이 인증서를 시스템 기본 'cacert'파일로 가져 오려고합니다. Java 설치를위한 시스템 기본 'cacerts'파일을 찾습니다. 기본 Java 설치의 cacerts 위치를 얻는 방법을 살펴보십시오 .
  4. 해당 cacerts 파일로 인증서를 가져옵니다. sudo keytool -importcert -file certs.der -keystore <path-to-cacerts>기본 cacerts 암호는 'changeit'입니다.

인증서가 FQDN에 대해 발급되고 Java 코드의 IP 주소로 연결하려는 경우 인증서 자체를 엉망으로 만드는 대신 코드에서이 문제를 수정해야합니다. FQDN으로 연결하도록 코드를 변경하십시오. 개발 컴퓨터에서 FQDN을 확인할 수없는 경우 호스트 파일에 추가하거나이 FQDN을 확인할 수있는 DNS 서버로 컴퓨터를 구성합니다.


"개발 컴퓨터에서 FQDN을 확인할 수없는 경우 간단히 호스트 파일에 추가"– 도움이되었습니다. 감사합니다!
Woland 2011

나는 똑같은 일을했지만 여전히 문제가 지속됩니다. 이 방법을 사용하여 수행 할 수있는 다른 작업이 있습니까?
pkgajulapalli

9

다른 답변이 여기에서 제안하는 것과 달리 코드를 변경하거나 SSL을 비활성화하는 대신 인증서에 제목 대체 이름을 추가하여이 문제를 올바른 방법으로 해결했습니다. "제목 대체 이름이 없습니다"라는 예외가 명확하게 표시되면 올바른 방법으로 추가해야합니다.

단계별로 이해하려면링크를 참조하십시오 .

위의 오류는 JKS 파일에 애플리케이션에 액세스하려는 필수 도메인이 없음을 의미합니다. 여러 도메인을 추가하려면 Open SSL 및 키 도구를 사용해야합니다.

  1. openssl.cnf를 현재 디렉토리에 복사합니다.
  2. echo '[ subject_alt_name ]' >> openssl.cnf
  3. echo 'subjectAltName = DNS:example.mydomain1.com, DNS:example.mydomain2.com, DNS:example.mydomain3.com, DNS: localhost'>> openssl.cnf
  4. openssl req -x509 -nodes -newkey rsa:2048 -config openssl.cnf -extensions subject_alt_name -keyout private.key -out self-signed.pem -subj '/C=gb/ST=edinburgh/L=edinburgh/O=mygroup/OU=servicing/CN=www.example.com/emailAddress=postmaster@example.com' -days 365
  5. 공개 키 (.pem) 파일을 PKS12 형식으로 내 보냅니다. 암호를 입력하라는 메시지가 표시됩니다.

    openssl pkcs12 -export -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in
    self-signed.pem -inkey private.key -name myalias -out keystore.p12
  6. 자체 서명 된 PEM (Keystore)에서 a.JKS 만들기

    keytool -importkeystore -destkeystore keystore.jks -deststoretype PKCS12 -srcstoretype PKCS12 -srckeystore keystore.p12
  7. 위의 키 저장소 또는 JKS 파일에서 인증서 생성

    keytool -export -keystore keystore.jks -alias myalias -file selfsigned.crt
  8. 위의 인증서는 자체 서명되고 CA에 의해 검증되지 않았으므로 Truststore에 추가해야합니다 (MAC의 경우 아래 위치에있는 Cacerts 파일, Windows의 경우 JDK가 설치된 위치를 확인하십시오.)

    sudo keytool -importcert -file selfsigned.crt -alias myalias -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

여기에이 링크에 게시 원래 답변 .


4

모든 SSL 검증을 비활성화하고 싶지 않을 수 있으므로 대안보다 약간 덜 무서운 이것을 통해 hostName 검증을 비활성화 할 수 있습니다.

HttpsURLConnection.setDefaultHostnameVerifier(
    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

[편집하다]

conapart3에서 언급했듯이 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER이제는 더 이상 사용되지 않으므로 이후 버전에서 제거 될 수 있으므로 모든 확인이 해제 된 솔루션은 피할 것이라고 말하지만 나중에 직접 롤링해야 할 수도 있습니다.


2
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER이제 더 이상 사용되지 않습니다.
conapart3

3

이 오류가 발생하는 문제는 "qatest / webService"대신 전체 URL "qatest.ourCompany.com/webService"를 사용하여 해결되었습니다. 그 이유는 보안 인증서에 "* .ourCompany.com"과 같은 와일드 카드가 있기 때문입니다. 전체 주소를 입력하면 예외가 사라졌습니다. 도움이 되었기를 바랍니다.


2

https://stackoverflow.com/a/53491151/1909708 에서 이미 답변했습니다 .

인증서 일반 이름 ( CN인증서 Subject)이나 대체 이름 ( Subject Alternative Name인증서)이 대상 호스트 이름 또는 IP 주소와 일치 하지 않기 때문에 실패합니다 .

예를 들어, JVM WW.XX.YY.ZZ에서 DNS 이름 ( https://stackoverflow.com )이 아닌 IP 주소 ( ) 에 연결을 시도 할 때 Java 신뢰 저장소에 저장된 인증서 때문에 HTTPS 연결이 실패합니다.cacerts 일반 이름 (또는 stackexchange.com 또는 * .stackoverflow.com 등과 같은 인증서 대체 이름)을 대상 주소와 일치시킵니다.

https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#HostnameVerifier를 확인하십시오.

    HttpsURLConnection urlConnection = (HttpsURLConnection) new URL("https://WW.XX.YY.ZZ/api/verify").openConnection();
    urlConnection.setSSLSocketFactory(socketFactory());
    urlConnection.setDoOutput(true);
    urlConnection.setRequestMethod("GET");
    urlConnection.setUseCaches(false);
    urlConnection.setHostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession sslSession) {
            return true;
        }
    });
    urlConnection.getOutputStream();

위에서 HostnameVerifier항상 반환되는 구현 된 객체를 전달했습니다 true.

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

1

Spring Boot의 경우 RestTemplate:

  • org.apache.httpcomponents.httpcore종속성 추가
  • 사용 NoopHostnameVerifierSSL 공장을 위해 :

    SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(new URL("file:pathToServerKeyStore"), storePassword)
    //        .loadKeyMaterial(new URL("file:pathToClientKeyStore"), storePassword, storePassword)
            .build();
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);
    RestTemplate restTemplate = new RestTemplate(factory);

0

이 같은 오류 메시지가 나타나면이 질문에 답했습니다. 그러나 제 경우 에는 동일한 서버로 향하는 서로 다른 하위 도메인 ( http://example1.xxx.com/someservicehttp://example2.yyy.com/someservice )을 가진 두 개의 URL 이있었습니다. 이 서버에는 * .xxx.com 도메인에 대해 하나의 와일드 카드 인증서 만 있습니다. 두 번째 도메인을 통해 서비스를 사용할 때 발견 된 인증서 (* .xxx.com)가 요청 된 도메인 (* .yyy.com)과 일치하지 않고 오류가 발생합니다.

이 경우 SSL 보안을 낮춰 이러한 오류 메시지를 수정하지 말고 서버와 인증서를 확인해야합니다.


0
public class RESTfulClientSSL {

    static TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // TODO Auto-generated method stub
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // TODO Auto-generated method stub
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }
    }};

    public class NullHostNameVerifier implements HostnameVerifier {
        /*
         * (non-Javadoc)
         *
         * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String,
         * javax.net.ssl.SSLSession)
         */
        @Override
        public boolean verify(String arg0, SSLSession arg1) {
            // TODO Auto-generated method stub
            return true;
        }
    }

    public static void main(String[] args) {

        HttpURLConnection connection = null;
        try {

            HttpsURLConnection.setDefaultHostnameVerifier(new RESTfulwalkthroughCer().new NullHostNameVerifier());
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());


            String uriString = "https://172.20.20.12:9443/rest/hr/exposed/service";
            URL url = new URL(uriString);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            //connection.setRequestMethod("POST");

            BASE64Encoder encoder = new BASE64Encoder();
            String username = "admin";
            String password = "admin";
            String encodedCredential = encoder.encode((username + ":" + password).getBytes());
            connection.setRequestProperty("Authorization", "Basic " + encodedCredential);

            connection.connect();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                StringBuffer stringBuffer = new StringBuffer();
                String line = "";
                while ((line = reader.readLine()) != null) {
                    stringBuffer.append(line);
                }
                String content = stringBuffer.toString();
                System.out.println(content);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
}

1
코드에 설명 텍스트를 추가하십시오. 참조 stackoverflow.com/help/how-to-answer
jasie

1
이것은 보안 결함입니다. 이것이 처음에 인증서 확인을 비활성화하는 방법입니다. 이 솔루션을 복사하여 붙여 넣는 모든 사람은 소프트웨어에 보안 버그를 만듭니다.
Marek Puchalski

0

springboot에서 양방향 SSL을 진행했습니다. 모든 올바른 구성 서비스 tomcat 서버 및 서비스 호출자 RestTemplate을 만들었습니다. 하지만 "java.security.cert.CertificateException : 제목 대체 이름이 없습니다."라는 오류가 발생했습니다 .

솔루션을 살펴본 후 JVM 에이 인증서가 필요하다는 것을 알았습니다. 그렇지 않으면 핸드 쉐이킹 오류가 발생합니다.

이제 이것을 JVM에 추가하는 방법.

jre / lib / security / cacerts 파일로 이동하십시오. jvm의이 cacerts 파일에 서버 인증서 파일을 추가해야합니다.

Windows의 명령 줄을 통해 cacerts 파일에 서버 인증서를 추가하는 명령입니다.

C : \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -import -noprompt -trustcacerts -alias sslserver -file E : \ spring_cloud_sachin \ ssl_keys \ sslserver.cer -keystore cacerts -storepass changeit

서버 인증서가 설치되었는지 확인하십시오.

C : \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -list -keystore cacerts

설치된 인증서 목록을 볼 수 있습니다.

자세한 내용 : https://sachin4java.blogspot.com/2019/08/javasecuritycertcertificateexception-no.html


0

인증서의 CN에 해당하는 IP로 호스트 항목을 추가하십시오.

CN = someSubdomain.someorganisation.com

이제 URL에 액세스하려는 CN 이름으로 IP를 업데이트하십시오.

그것은 나를 위해 일했습니다.


0

이 코드는 매력처럼 작동하며 나머지 코드에는 restTemple 객체를 사용합니다.

  RestTemplate restTemplate = new RestTemplate();   
  TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) {
                return true;
            }

        };

        SSLContext sslContext = null;
        try {
            sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);

        restTemplate.setRequestFactory(requestFactory);
}

0

CN 및 SAN (주체 대체 이름)이 모두있는 인증서가있는 경우 CN 콘텐츠를 기반으로 요청하면 해당 특정 콘텐츠도 SAN 아래에 있어야합니다. 그렇지 않으면 해당 오류와 함께 실패합니다.

제 경우에는 CN에 무언가가 있었고 SAN에는 다른 것이있었습니다. SAN URL을 사용해야했는데 제대로 작동했습니다.


-3

C : \ Windows \ System32 \ drivers \ etc의 폴더에있는 호스트 파일에 IP 주소를 추가합니다. 또한 IP 주소의 IP 및 도메인 이름을 추가하십시오. 예 : aaa.bbb.ccc.ddd abc@def.com


-5

다음과 같은 방법으로 문제를 해결했습니다.

1. 수업 만들기. 클래스에 빈 구현이 있습니다.

class MyTrustManager implements X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
}

public void checkClientTrusted(X509Certificate[] certs, String authType) {
}

public void checkServerTrusted(X509Certificate[] certs, String authType) {
}

@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString)
        throws CertificateException {
    // TODO Auto-generated method stub

}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString)
        throws CertificateException {
    // TODO Auto-generated method stub

}

2. 메서드 생성

private static void disableSSL() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { new MyTrustManager() };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

  1. 예외가 발생하는 disableSSL () 메서드를 호출합니다. 잘 작동했습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.