다음은 netty 프로젝트의 HttpSnoop 서버 예제를 기반으로 한 솔루션입니다.
클라이언트 측 파이프 라인을 설정하는 경우 다음과 같이 SSL 엔진을 설정해야합니다 :
키 스토어에 추가하여 신뢰 저장소를 설정하기 위해 다음과 같이
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = pipeline();
// Uncomment the following line if you want HTTPS
SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
engine.setUseClientMode(false);
engine.setNeedClientAuth(true);
pipeline.addLast("ssl", new SslHandler(engine));
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("logger", new RequestAuditLogger());
// Uncomment the following line if you don't want to handle HttpChunks.
pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
pipeline.addLast("outputLogger", new ResponseAuditLogger());
pipeline.addLast("encoder", new HttpResponseEncoder());
// Remove the following line if you don't want automatic content compression.
pipeline.addLast("deflater", new HttpContentCompressor());
pipeline.addLast("handler", new HttpSnoopServerHandler());
return pipeline;
}
}
그런 다음의 SSLContext는 (SecureChatSslContextFactory) 수정해야합니다 :
public final class SecureChatSslContextFactory {
private static Logger logger = LoggerFactory.getLogger(SecureChatSslContextFactory.class);
private static final String PROTOCOL = "TLS";
private static final SSLContext SERVER_CONTEXT;
private static final SSLContext CLIENT_CONTEXT;
static {
SSLContext serverContext = null;
SSLContext clientContext = null;
// get keystore and trustore locations and passwords
String keyStoreLocation = System.getProperty("javax.net.ssl.keyStore");
String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore");
String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(KeyStoreStreamManager.asInputStream(keyStoreLocation),
keyStorePassword.toCharArray());
// Set up key manager factory to use our key store
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyStorePassword.toCharArray());
// truststore
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(KeyStoreStreamManager.asInputStream(trustStoreLocation),
trustStorePassword.toCharArray());
// set up trust manager factory to use our trust store
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ts);
// Initialize the SSLContext to work with our key managers.
serverContext = SSLContext.getInstance(PROTOCOL);
serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (Exception e) {
throw new Error(
"Failed to initialize the server-side SSLContext", e);
}
try {
clientContext = SSLContext.getInstance(PROTOCOL);
clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null);
} catch (Exception e) {
throw new Error(
"Failed to initialize the client-side SSLContext", e);
}
SERVER_CONTEXT = serverContext;
CLIENT_CONTEXT = clientContext;
}
public static SSLContext getServerContext() {
return SERVER_CONTEXT;
}
public static SSLContext getClientContext() {
return CLIENT_CONTEXT;
}
private SecureChatSslContextFactory() {
// Unused
}
}
저는 CStepnitz의 답변에 대해 의견을 말했습니다. SslEngine 문서에서 : 클라이언트 인증을 요구하도록 엔진을 구성합니다. 이 옵션은 서버 모드의 엔진에만 유용합니다. 그가 말한대로 클라이언트 쪽이 아닙니다. – user1792307
@CStepnitz : TrustManager에서 어떤 종류의 인증서를 사용할 수 있는지 알고 있습니까? 나는 매우 유사한 아키텍처를 가지고 있지만 클라이언트는 ECC 인증서를 보내고있다. (그리고 인증서의 곡선이 인식되지 않기 때문에 핸드 셰이크가 실패한다.) RSA 인증서가 받아 들여진다. – favicon