Program Tip

Java가 SSL 핸드 셰이크 중에 클라이언트 인증서를 보내지 않는 이유는 무엇입니까?

programtip 2020. 12. 1. 19:38
반응형

Java가 SSL 핸드 셰이크 중에 클라이언트 인증서를 보내지 않는 이유는 무엇입니까?


보안 웹 서비스에 연결하려고합니다.

내 키 저장소와 신뢰 저장소가 올바르게 설정 되었음에도 불구하고 핸드 셰이크 실패가 발생했습니다.

며칠의 좌절과 끊임없는 인터넷 검색과 주변의 모든 사람들에게 물어 본 후 유일한 문제는 자바가 핸드 셰이크 중에 클라이언트 인증서를 서버에 보내지 않기로 결정했다는 것입니다.

구체적으로 특별히:

  1. 서버가 클라이언트 인증서 (CN = RootCA)를 요청했습니다. 즉, "루트 CA가 서명 한 인증서를 줘"
  2. Java는 키 저장소를 조사하고 "RootCA"에서 발급 한 "SubCA"에 의해 서명 된 클라이언트 인증서 만 찾았습니다. 트러스트 스토어를 들여다 보는 것도 귀찮게하지 않았어 ...
  3. 안타깝게도 "SubCA"인증서를 키 저장소에 추가하려고했지만 전혀 도움이되지 않았습니다. 인증서가 키 저장소에로드되었는지 확인했습니다. 하지만 KeyManager는 클라이언트 인증서를 제외한 모든 인증서를 무시합니다.
  4. 위의 모든 것은 Java가 서버의 요청을 충족시키는 인증서가 없다고 결정하고 아무것도 보내지 않는다고 결정한다는 사실로 이어집니다 ... tadaaa 핸드 셰이크 실패 :-(

내 질문 :

  1. KeyManager가 클라이언트 인증서 만로드하고 나머지는 무시하도록 "인증 체인이 끊어진"방식으로 "SubCA"인증서를 키 저장소에 추가 할 수 있습니까? (Chrome 및 openssl은 Java를 사용할 수없는 이유를 파악할 수 있습니까?- "SubCA"인증서는 항상 신뢰할 수있는 기관으로 별도로 제공되므로 Chrome은 핸드 셰이크 중에 클라이언트 인증서와 함께 올바르게 포장합니다.)
  2. 이것은 서버 측의 공식적인 "구성 문제"입니까? 서버가 타사입니다. 나는 서버가 "SubCA"기관이 우리에게 제공 한 것이므로 서명 된 인증서를 요청할 것으로 예상합니다. 나는 이것이 크롬과 openssl에서 작동한다는 사실이 그들이 "덜 제한적"이고 자바가 "책에 의해"가고 실패하기 때문이라고 생각한다.

나는 이것에 대한 더러운 해결 방법을 모아 놓았지만 그것에 대해별로 행복하지 않으므로 누군가가 나를 위해 이것을 명확히 할 수 있다면 기뻐할 것입니다.


클라이언트 인증서 및 개인 키가있는 항목과 연결하지 않고 중간 CA 인증서를 키 저장소로 가져 왔을 수 있습니다. 을 사용하여 이것을 볼 수 있어야합니다 keytool -v -list -keystore store.jks. 별칭 항목 당 하나의 인증서 만받는 경우에는 함께 있지 않습니다.

인증서와 체인을 함께 개인 키가있는 키 저장소 별칭으로 가져와야합니다.

개인 키가있는 키 저장소 별칭을 찾으려면 keytool -list -keystore store.jks(여기서 JKS 저장소 유형을 가정합니다)를 사용합니다. 이것은 다음과 같은 것을 알려줄 것입니다.

Your keystore contains 1 entry

myalias, Feb 15, 2012, PrivateKeyEntry, 
Certificate fingerprint (MD5): xxxxxxxx

여기서 별칭은 myalias입니다. -v이 외에도 사용 하면 Alias Name: myalias.

아직 별도로 가지고 있지 않은 경우 키 저장소에서 클라이언트 인증서를 내 보냅니다.

keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias

그러면 PEM 파일이 제공됩니다.

텍스트 편집기 (또는 cat)를 사용하여 bundle.pem해당 클라이언트 인증서와 중간 CA 인증서 (원하는 경우 루트 CA 인증서 자체)가 포함 된 파일을 준비 하여 (원하는 경우 루트 CA 인증서 자체) 클라이언트 인증서가 시작되고 해당 발급자에 있도록합니다. 인증서가 바로 아래에 있습니다.

이것은 다음과 같아야합니다.

-----BEGIN CERTIFICATE-----
MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----

이제이 번들을 개인 키가있는 별칭으로 다시 함께 가져옵니다.

keytool -importcert -keystore store.jks -alias myalias -file bundle.pem

여기에 추가로 %> openssl s_client -connect host.example.com:443을 사용 하고 덤프를보고 모든 기본 인증서가 클라이언트에 대해 유효한지 확인할 수 있습니다. 출력 하단에서 이것을 찾고 있습니다. 반환 코드 확인 : 0 (확인)

-showcerts 를 추가 하면 키 체인에로드 한 호스트 인증서와 함께 전송 된 키 체인의 모든 정보가 덤프됩니다.


문제는 중간 인증서에 의해 서명 된 클라이언트 인증서를 사용할 때 자바가 찾을 수 있도록 트러 스토어에 중간 인증서를 포함해야한다는 것입니다. 솔로 또는 루트 발행 ca.

참고 URL : https://stackoverflow.com/questions/9299133/why-doesnt-java-send-the-client-certificate-during-ssl-handshake

반응형