Javax.Net.SSL.SSLHandshakeException 오류 수정

Sheeraz Gul 2023년6월20일
  1. Java의 SSL 핸드셰이크
  2. 서버 인증서 누락으로 인한 SSLHandshakeException 수정
  3. 신뢰할 수 없는 서버 인증서로 인해 SSLHandShakeException 수정
  4. 잘못된 인증서로 인해 SSLHandShakeException 수정
  5. 호환되지 않는 SSL 버전 및 암호 제품군으로 인해 SSLHandShakeException 수정
Javax.Net.SSL.SSLHandshakeException 오류 수정

이 자습서는 Java의 javax.net.ssl.SSLHandshakeException 오류를 보여줍니다.

Java의 SSL 핸드셰이크

SSL 핸드셰이크는 클라이언트와 서버가 인터넷을 통한 연결을 보호하는 데 필요한 신뢰 및 물류를 설정하는 데 사용됩니다. 따라야 하는 SSL 핸드셰이크 작업에는 일반적인 단계가 있습니다.

  1. 먼저 클라이언트는 가능한 모든 암호화 제품군 및 SSL 버전 목록을 제공합니다.
  2. 그런 다음 서버는 인증서로 응답할 특정 암호화 제품군 및 SSL 버전에 동의합니다.
  3. 그런 다음 클라이언트는 주어진 인증서에서 공개 키를 추출하고 새로운 암호화된 사전 마스터 키로 응답합니다.
  4. 그런 다음 서버는 개인 키를 사용하여 사전 마스터 키를 해독합니다.
  5. 그런 다음 클라이언트와 서버는 사전 마스터 키를 함께 사용하여 공유 비밀을 계산합니다.
  6. 마지막으로 클라이언트와 서버는 공유 비밀의 성공적인 암호화 및 암호 해독을 확인하는 메시지를 교환합니다.

SSL 핸드셰이크에는 두 가지 유형이 있습니다. 첫 번째는 서버가 모든 클라이언트를 신뢰하도록 하는 단방향 SSL이고 두 번째는 클라이언트와 서버가 서로의 인증서를 수락해야 하는 양방향 SSL입니다.

SSL 핸드셰이크를 이해했으면 이제 SSLHandShakeException에 대해 자세히 논의할 수 있습니다. 아래 주어진 SSLHandShakeException의 두 가지 시나리오가 있습니다.

서버 인증서 누락으로 인한 SSLHandshakeException 수정

클라이언트가 서버에 연결할 때 SSL 핸드셰이크 작업이 인증서를 받지 못한 경우 아래에 언급된 대로 SSLHandShakeException이 발생합니다.

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  Received fatal alert: handshake_failure

이 문제를 해결하려면 위의 모든 단계를 따르십시오. 이 문제는 Keystore 또는 시스템 속성이 제대로 입력되지 않았을 때 발생합니다.

키 저장소는 기관에서 제공하는 인증서이거나 JDK의 keytool 기능을 사용하여 키 저장소를 만들 수도 있습니다. 다음은 키 저장소의 예입니다.

$ keytool -genkey -keypass password \
                  -storepass password \
                  -keystore Server_Keystore.jks

위의 keytool 코드는 Keystore 파일에 작성됩니다. 이제 keytool을 사용하여 위에서 생성된 키 저장소 파일에서 공용 인증서를 추출할 수 있습니다.

$ keytool -export -storepass password \
                  -file NewServer.cer \
                  -keystore Server_Keystore.jks

위의 코드는 키 저장소에서 NewServer.cer 파일로 공용 인증서를 내보냅니다. 이제 클라이언트의 Truststore에 추가할 수 있습니다.

$ keytool -import -v -trustcacerts \
                     -file NewServer.cer \
                     -keypass password \
                     -storepass password \
                     -keystore Client_Truststore.jks

이제 서버용 키 저장소와 클라이언트용 신뢰 저장소가 생성되었습니다. 다음 명령을 사용하여 서버에 시스템 속성으로 전달할 수 있습니다.

-Djavax.net.ssl.keyStore=Client_Keystore.jks -Djavax.net.ssl.keyStorePassword=password

시스템 속성에 필요합니다. 키 저장소 파일 경로는 절대적이거나 명령이 호출되는 동일한 디렉토리에 키 저장소 파일을 배치해야 합니다.

상대 경로는 지원되지 않습니다. 이 프로세스를 수행하면 누락된 인증서 오류가 해결되고 더 이상 SSLHandShakeException이 발생하지 않습니다.

신뢰할 수 없는 서버 인증서로 인해 SSLHandShakeException 수정

SSLHandShakeException의 다른 이유는 신뢰할 수 없는 서버 인증서입니다. 서버가 기관에서 서명하지 않은 자체 서명된 인증서를 사용하는 경우 다음 오류가 발생합니다.

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  sun.security.validator.ValidatorException:
  PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
  unable to find valid certification path to requested target

이 예외는 기본 저장소가 아닌 엔터티가 인증서에 서명할 때마다 발생합니다. JDK의 기본 Truststore는 사용 중인 공통 인증서에 대한 정보를 제공합니다.

이 문제는 클라이언트가 서버에서 제시한 인증서를 강제로 신뢰하도록 하여 해결할 수 있습니다. 위에서 생성한 Truststore를 사용하고 시스템 속성으로 클라이언트에 전달해야 합니다.

-Djavax.net.ssl.trustStore=Client_Truststore.jks -Djavax.net.ssl.trustStorePassword=password

이렇게 하면 예외가 해결되지만 이상적인 상황은 아닙니다. 이상적인 상황에서는 인증 기관(CA)에서 인증해야 하는 자체 서명된 인증서를 사용할 수 있으며 클라이언트는 기본적으로 이를 신뢰할 수 있습니다.

잘못된 인증서로 인해 SSLHandShakeException 수정

잘못된 인증서로 인해 핸드셰이크가 실패할 수도 있습니다. 인증서가 제대로 생성되지 않으면 SSLHandShakeException이 발생합니다.

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
    java.security.cert.CertificateException:
    No name matching localhost found

인증서가 제대로 생성되었는지 확인하려면 다음 명령을 실행합니다.

keytool -v -list -keystore Server_Keystore.jks

위의 명령은 키 저장소 소유자의 세부 정보를 표시합니다.

...
Owner: CN=localhost, OU=technology, O=delftstack, L=city, ST=state, C=xx
..

소유자의 CN은 서버의 CN과 일치해야 하며, 일치하지 않으면 CN이 다르기 때문에 위와 동일한 예외가 발생합니다.

호환되지 않는 SSL 버전 및 암호 제품군으로 인해 SSLHandShakeException 수정

SSL 핸드셰이크 작업 중에는 서로 다른 버전의 SSL, TLS 등과 같은 다양한 암호화 프로토콜이 있을 수 있습니다. 클라이언트와 서버는 핸드셰이크에서 암호화 프로토콜 및 버전에 동의해야 하지만 다음을 위해 SSL은 TLS로 대체됩니다. 암호화 강도.

이제 예를 들어 서버가 SSL3 프로토콜을 사용하고 클라이언트가 TLS1.3 프로토콜을 사용하는 경우 둘 다 암호화 프로토콜에 동의할 수 없으며 SSLHandShakeException이 발생합니다.

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

이 문제를 해결하려면 클라이언트와 서버가 동일하거나 호환되는 암호화 프로토콜을 사용하고 있는지 확인해야 합니다.

마찬가지로 호환되는 Cipher Suite도 필요합니다. 핸드셰이크 중에 클라이언트는 암호 목록을 제공하고 서버는 사용할 암호를 선택합니다.

서버가 적절한 암호를 선택할 수 없는 경우 코드는 다음 SSLHandShakeException을 발생시킵니다.

Exception in thread "main" javax.net.ssl.SSLHandshakeException:
  Received fatal alert: handshake_failure

일반적으로 클라이언트와 서버는 다양한 암호 제품군을 사용합니다. 이 오류가 발생할 수 있는 이유입니다. 서버가 매우 선별적인 암호를 선택했기 때문에 오류가 발생합니다.

이 문제를 방지하기 위해 서버는 보안에도 좋은 선택적 암호 목록을 사용합니다.

작가: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook

관련 문장 - Java Error