2017-11-18 33 views
1

내 목표 : 제트 임베디드 (Jetty Embedded)를 사용하면 간단하게 사용할 수 있습니다. interface은 Java KeyStore를 사용하지 않고 TLS 인증서 용 외부 소스 통합을 허용합니다.JKS가없는 Embedded Jetty의 TLS

이렇게하면 분산 웹 서비스를 구축 할 때 유연성이 향상됩니다 (내 경우 experimental, self-hosted CDN).

그러나 통합을 구축하는 데 문제가 있습니다. 스텁 구현은 in this repository입니다.

내가 시도한 것 :key managertrust manager을 교체하고 그 안에있는 모든 기능에 중단 점을 설정해 보았습니다. 그러나 서버에 액세스하려고하면 이러한 중단 점이 실행되지 않습니다. 대신,이 오류가 발생 해요 :

javax.net.ssl.SSLHandshakeException: no cipher suites in common 
    at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478) 
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535) 
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:813) 
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781) 
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) 
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:621) 
    at org.eclipse.jetty.server.HttpConnection.fillRequestBuffer(HttpConnection.java:322) 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:231) 
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) 
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112) 
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:261) 
    at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:150) 
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112) 
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) 
    at java.lang.Thread.run(Thread.java:748) 

나는 "표준"부두 설치를 분석 시도하는 키 스토어에서, 그러나 매우 운이없는 인증서. Jetty가 내가 대체해야하는 암호/인증서 정보를 얻고 있다는 요점을 찾지 못했습니다.

내 질문 : 방탄복을 Java KeyStore 및 TrustStore 대신 my own certificate source으로 어떻게 사용할 수 있습니까?

+1

이 예외는 일반적으로 서버가 개인 키와 일치하는 인증서를 찾을 수 없음을 나타냅니다. 분명히'KeyManager'가 올바르게 설치되지 않았거나, 이전에 호출되었을 것입니다. – EJP

+0

고맙습니다. 키 관리자가 "재고"버전과 내 제품에 어떻게 설치되어 있는지 추적하겠습니다. – Janoszen

답변

0

@EJP 그래서 여기 그것을하는 방법, 올바른 방향으로 절 지적 :이 수행해야 할 방법

가 여기에 있습니다. TLS를위한 부두를 설정

첫째 :

HttpConfiguration https = new HttpConfiguration(); 
https.addCustomizer(new SecureRequestCustomizer()); 
SslContextFactory sslContextFactory = new JettySslContextFactory(configuration.getSslProviders()); 
ServerConnector sslConnector = new ServerConnector(
    server, 
    new SslConnectionFactory(sslContextFactory, "http/1.1"), 
    new HttpConnectionFactory(https) 
); 
sslConnector.setPort(httpsPort); 

참고 클래스 JettySslContextFactory. 이 클래스는 X509ExtendedKeyManager 내장 - 더 확장하고 제공하기 위해 protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception 메소드를 오버라이드 (override)이 같은 정의의 KeyManager, 필요 : 그 외에도

@Override 
protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception { 
    return new KeyManager[] { 
     new JettyX509ExtendedKeyManager(certificateProviders) 
    }; 
} 

는 다음 단계가 모든 연결에서 실행됩니다 :

  1. SNI 일치 프로그램은 SNI 호스트 이름과상의됩니다. 이것은 SNI 호스트 이름을 사용할 수있는 유일한 장소 인 것 같습니다.
  2. 특정 키 유형 (EC 또는 RSA)에 대한 별칭 (키 ID 정렬)을 얻으려면 키 관리자를 참조하십시오. SNI 일치 자의 호스트 이름을 가져와야합니다. 그렇지 않으면 일치시킬 호스트 이름을 알 수 없기 때문입니다.
  3. 별칭 (키 ID)을 기반으로 개인 키와 인증서를 반환 할 수 있습니다.

적어도이 문제를 디버깅하여 수집 한 것입니다. 전체 코드는 is online here입니다.