2016-12-07 3 views
2

Java를 사용하여 웹 서비스에 대한 양방향 TSL 연결을 설정하려고합니다. 개인 키와 인증서 3 개의 인증서 체인이있는 pfx 인증서가 제공되었습니다.핸드 셰이크 실패 인증서 체인을 사용하는 클라이언트 키 교환

@Bean 
public Client weatherClient(Jaxb2Marshaller marshaller) throws Exception { 
    Client client = new Client(); 
    client.setDefaultUri("....."); 
    client.setMarshaller(marshaller); 
    client.setUnmarshaller(marshaller); 

    KeyStore ks = KeyStore.getInstance("PKCS12"); 
    ks.load(keyStore.getInputStream(), keyStorePassword.toCharArray()); 

    LOGGER.info("Loaded keystore: " + keyStore.getURI().toString()); 
    System.out.println("Loaded keystore: " + keyStore.getURI().toString()); 

    keyStore.getInputStream().close(); 


    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//KeyManagerFactory.getDefaultAlgorithm() 
    keyManagerFactory.init(ks, keyStorePassword.toCharArray()); 

    KeyStore ts = KeyStore.getInstance("PKCS12"); 
    ts.load(trustStore.getInputStream(), trustStorePassword.toCharArray());// 
    LOGGER.info("Loaded trustStore: " + trustStore.getURI().toString()); 
    System.out.println("Loaded trustStore: " + trustStore.getURI().toString()); 

    trustStore.getInputStream().close(); 

    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    trustManagerFactory.init(ts); 

    HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender(); 
    messageSender.setKeyManagers(keyManagerFactory.getKeyManagers()); 
    messageSender.setTrustManagers(trustManagerFactory.getTrustManagers()); 
    client.setMessageSender(messageSender); 
    return client; 
} 

지금까지 내가의 ClientHello과 및 인증서를 전송하는 ServerHello을 얻고, 내가 찾을 신뢰할 수있는 인증서를 얻을 다음은 자바 코드를 사용하여 스프링 프레임 워크입니다. 인증서를 찾을 수없는 인증서 요청이 있습니다.

*** CertificateRequest 
Cert Types: RSA, DSS 
Cert Authorities: 
<CN=Thawte SSL CA, O="Thawte, Inc.", C=US> 
.... 
.... 
*** ServerHelloDone 
Warning: no suitable certificate found - continuing without client authentication 
*** Certificate chain 
<Empty> 
*** 

lib/security/cacerts에 개별적으로 인증서를 추가했습니다. 첫 번째 인증서 교환은 인증서가 추가 된 유일한 장소 인 경우 동일한 동작을 수행하므로 cacerts keystore에서 발생합니다. 요청은 인증서 체인을 찾고 있지만 개인 키와 인증서 체인이있는 pkcs12로 KeyStore 개체로 가져 왔음에도 불구하고 인증서 체인을 찾을 수없는 것 같습니다. ClientKeyExchange 내가 위의 경고 때문 추정 한 후 어떤 도움을

내가 악수 실패를 얻고있다

UPDATE를 감상 할 수있다하지만 난 그것에 대해 잘못 될 수 있습니다.

*** ClientKeyExchange, RSA PreMasterSecret, TLSv1 
main, WRITE: TLSv1 Handshake, length = 269 
SESSION KEYGEN: 
PreMaster Secret: 
.... 
.... 
0000: B0 E2 38 5E 40 4E 7C C5       ..8^@N.. 
Server write IV: 
0000: 44 40 45 E1 82 45 15 9B       [email protected] 
main, WRITE: TLSv1 Change Cipher Spec, length = 1 
*** Finished 
verify_data: { 109, 220, 225, 98, 98, 233, 48, 215, 61, 50, 58, 207 } 
*** 
main, WRITE: TLSv1 Handshake, length = 40 
main, READ: TLSv1 Alert, length = 2 
main, RECV TLSv1 ALERT: fatal, handshake_failure 
%% Invalidated: [Session-1, SSL_RSA_WITH_3DES_EDE_CBC_SHA] 

UPDATE

내가 변수 -Djavax.net.ssl.keyStore= 로하지만 밖으로 나가 다음을받을 변수로 키 저장소를 추가하는 키 스토어를 추가하는 경우 상호 인증이 작동

. 코드에 지정된 키 저장소 및 신뢰 저장소를 발견하고 인증서 체인과 신뢰 저장소는 디버그

*** 
found key for : devcert 
chain [0] = [ 
[ 
    Version: V3 ...... 

*** 
adding as trusted cert: 
    Subject: 

그런 다음 빈 키 스토어가 표시되고 JVM의 cacerts에이 신뢰할 수있는 인증서로 사용에 표시됩니다.

keyStore is : 
keyStore type is : jks 
keyStore provider is : 
init keystore 
init keymanager of type SunX509 
trustStore is: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 
adding as trusted cert: 
    Subject: CN=ubuntu 

그러면 서버가 헬로 *** ServerHello, 해당하는 인증 키 저장소와

*** 
    Found trusted certificate: 
but the Certificate Request does find a matching certificate as above, unless it is added as a variable 
*** CertificateRequest 
Cert Types: RSA, DSS 
Cert Authorities: 
<CN=Thawte SSL CA, O="Thawte, Inc.", C=US> 
.... 
.... 
*** ServerHelloDone 
Warning: no suitable certificate found - continuing without client authentication 
*** Certificate chain 
<Empty> 
*** 

문제가 varible -Djavax.net.ssl.keyStore=

*** ServerHelloDone 
matching alias: devcert 
*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
로서 첨가

을 발견 TLSv1의

동적으로 변화하는 것을 볼 수 있기를 원하는 것처럼 프로그램 코드에서 키 스토어와 트러스트 스토어를 사용하고 싶습니다. 나중에

+0

수정 한 내용을 확인하려면 서버 SSL 로그를 검토해야합니다. 클라이언트가'Certificate' 메시지를 보내면 클라이언트 인증서가 작동했습니다. – EJP

+0

고마워요. 서버에 액세스 할 필요가 없습니다.하지만 클라이언트 키 교환 이후에 일부 데이터 교환이 오류를 일으키는 것으로 추측합니다. 서버에 잘못된 데이터가 전달 된 것일 수 있습니다. –

답변

1

아니요에게 개인 키가 제공되어야합니다. 이는 이미 주요 보안 침해입니다. 실제 문제는 인증서가 CertificateRequest 메시지에 언급 된 CA에 의해 서명되지 않았거나 여기에 언급 된 유형이 아닌 것입니다.

+0

디스크의 개인 키가있는 .pfx 파일이 제공되었습니다. SoapUI를 사용하여 인증서로 서비스에 연결할 수 있습니다.인증서는 키 알고리즘 : RSA –

+0

이고 Thawte가 서명하지 않았습니다. – EJP

+0

감사합니다. 브라우저에서 Thawte 인증서를 가져 와서 cacerts 키 저장소로 가져 왔습니다. 치명적이지는 않지만 serverHello 단계에서 description = certificate_unknown이 발생했습니다. –

관련 문제