2017-03-17 8 views
0

Mac OS에서 GRPC를 사용하여 Java 클라이언트를 NodeJS 서버에 연결하려고합니다. 나는 동일한 인증서를 사용하는 NodeJS 서버에 샘플 JS 클라이언트와 연결할 수 있지만 SSL 핸드 셰이크 문제를 지속적으로 얻고있다.GRPC Java 클라이언트 및 NodeJS 서버를 사용하는 디버그 ssl 연결 문제

서버 로그 : 더이 문제를 디버깅하는 방법에 대한 어떤 생각

chttp2_server.c:123] Handshaking failed: {"created":"@1489747510.536841000","description":"Handshake read failed","file":"../src/core/lib/security/transport/security_handshaker.c","file_line":238,"referenced_errors":[{"created":"@1489747510.536836000","description":"Socket closed","fd":27,"file":"../src/core/lib/iomgr/tcp_posix.c","file_line":249,"target_address":"ipv4:127.0.0.1:61964"}]} 

클라이언트

public class Connection implements IConnection { 

    private static final Logger log = LogManager.getLogger(Connection.class.getName()); 
    private final String host; 
    private final int port; 

    public Connection(String host, int port) { 
     this.host = host; 
     this.port = port; 
    } 

    /*public ManagedChannelBuilder getInsecure() { 
     return ManagedChannelBuilder.forAddress(host, port) 
       .usePlaintext(true); 
    }*/ 

    public ManagedChannelBuilder getSecure() { 
     ManagedChannelBuilder<?> channelBuilder = null; 
     Optional<SslContext> optional = getSslContext(); 
     if (optional.isPresent()) { 
      final SslContext sslContext = optional.get(); 
      log.info("building channel for connection"); 
      channelBuilder = NettyChannelBuilder.forAddress(host, port) 
        .overrideAuthority("localhost") 
        .negotiationType(NegotiationType.TLS) 
        .usePlaintext(false) 
        .sslContext(sslContext); 
     } 
     return channelBuilder; 
    } 

    private Optional<SslContext> getSslContext() { 
     SslContext sslContext = null; 
     Optional<ICertificateRepository> optional = getCertificates(); 
     if (optional.isPresent()) { 
      final ICertificateRepository certificateRepo = optional.get(); 
      final File publicCert = certificateRepo.getPublicCert(); 
      final File clientCert = certificateRepo.getClientCert(); 
      final File clientKey = certificateRepo.getClientKey(); 
      try { 
       java.security.Security.addProvider(
         new org.bouncycastle.jce.provider.BouncyCastleProvider() 
       ); 
       log.info("attempting to create the ssl context"); 
       sslContext = GrpcSslContexts.forClient() 
         .startTls(true) 
         .sslProvider(defaultSslProvider()) 
         .trustManager(publicCert) 
         .keyManager(clientCert, clientKey) 
         .ciphers(null) //testing 
         .build(); 
      } catch (SSLException se) { 
       log.error("ssl exception before connection attempt {}", se); 
      } 
     } 
     Optional<SslContext> sslOptional = Optional.ofNullable(sslContext); 
     return sslOptional; 
    } 

    private Optional<ICertificateRepository> getCertificates() { 
     ICertificateRepository certificateRepo = null; 
     try { 
      certificateRepo = new CertificateRepository(); 
      log.info("path: {} | {} | {}", certificateRepo.getPublicCert().getAbsolutePath(), 
        certificateRepo.getPublicCert().exists(), certificateRepo.getPublicCert().isFile()); 
      log.info("clientCert: {} | {}", certificateRepo.getClientCert().getAbsolutePath(), 
        certificateRepo.getClientCert().exists()); 
      log.info("clientKey: {} | {}", certificateRepo.getClientKey().getAbsolutePath(), 
        certificateRepo.getClientKey().exists()); 
     } catch (Exception fe) { 
      log.error("unable to read SSL certificates in keys directory"); 
     } 
     Optional<ICertificateRepository> optional = Optional.ofNullable(certificateRepo); 
     return optional; 
    } 

    private static SslProvider defaultSslProvider() { 
     log.info("is OpenSsl available: {}", OpenSsl.isAvailable()); 
     return OpenSsl.isAvailable() ? SslProvider.OPENSSL : SslProvider.JDK; 
    } 
} 

인증서 파일 위치가 올바른지 및 인증서 저장소는 다음과 같이 생성됩니다

public CertificateRepository() { 
     final ClassLoader classLoader = getClass().getClassLoader(); 
     try { 
      this.publicCert = new File(classLoader.getResource(
        new StringBuilder(MonetagoProps.BASE_DIR_FOR_CERTS) 
          .append(TestProps.CERT_NAME) 
          .toString()).getFile()); 
      this.clientCert = new File(classLoader.getResource(
        new StringBuilder(MonetagoProps.BASE_DIR_FOR_CERTS) 
          .append(MonetagoProps.CLIENT_CERT_NAME) 
          .toString()).getFile()); 
      this.clientKey = new File(classLoader.getResource(
        new StringBuilder(TestProps.BASE_DIR_FOR_CERTS) 
          .append(TestProps.CLIENT_KEY_NAME) 
          .toString()).getFile()); 
     } catch (Exception fe) { 
      log.error("unable to read ssl certificate files for testConnection"); 
      throw new IllegalStateException("unable to read ssl certificate files for test Connection"); 
     } 
    } 

답변

0

채널 빌더에서 usePlaintext (false) 호출을 주석 처리하고 서버와의 SSL 연결을 설정할 수있었습니다.

channelBuilder = NettyChannelBuilder.forAddress(host, port) 
        .overrideAuthority("localhost") 
        .negotiationType(NegotiationType.TLS) 
        **//.usePlaintext(false)** 
        .sslContext(sslContext);