2017-12-21 59 views
0

gRPC를 사용하여 내 서버에 연결하는 데 문제가 있습니다. 서버는 인증서 파일 (rpc.cert 및 rpc.key)을 사용하여 인증하지만 해당 파일을 포함시키는 방법을 모르겠습니다. 현재이 내가 위의 코드를 사용하여grpc의 보안 연결

ManagedChannel channel = OkHttpChannelBuilder.forAddress("127.0.0.1", 9111) 
.usePlaintext(true) 
.build(); 

를 연결하는 데 사용하는 코드는이 오류

io.grpc.StatusRuntimeException: UNAVAILABLE: End of stream or IOExceptio 
    at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.jav 
    at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:202) 
    at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:131) 
    at com.dcrwallet.grpc.WalletLoaderServiceGrpc$WalletLoaderServiceBlo 
    at com.decrediton.MainActivity$2.onClick(MainActivity.java:86) 
    at android.view.View.performClick(View.java:5675) 
    at android.view.View$PerformClick.run(View.java:22641) 
    at android.os.Handler.handleCallback(Handler.java:836) 
    at android.os.Handler.dispatchMessage(Handler.java:103) 
    at android.os.Looper.loop(Looper.java:203) 
    at android.app.ActivityThread.main(ActivityThread.java:6285) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(Zygote 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924) 
Caused by: javax.net.ssl.SSLHandshakeException: Handshake failed 
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:444) 
    at io.grpc.okhttp.OkHttpProtocolNegotiator.negotiate(OkHttpProtocolNegotiator.java:93) 
    at io.grpc.okhttp.OkHttpProtocolNegotiator$AndroidNegotiator.negotiate(OkHttpProtocolNegotiator.java:159) 
    at io.grpc.okhttp.OkHttpTlsUpgrader.upgrade(OkHttpTlsUpgrader.java:63) 
    at io.grpc.okhttp.OkHttpClientTransport$1.run(OkHttpClientTransport.java:429) 
    at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb036ce80: Failure in SSL library, usually a protocol error error:1000006b:SSL routines:OPENSSL_internal:BAD_ECC_CERT (external/boringssl/src/ssl/s3_clnt.c:957 0xa74a5d15:0x00000000) 
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:362) 

내가 안드로이드에 grpc의 okhttp 사용에 대한 모든 문서를 찾을 수 없습니다 던졌습니다입니다. google에 의한 gRPC 문서에는 오류가 포함되어 있지 않으므로 오류에 대해 어떻게해야할지 잘 모릅니다. 감사합니다.

답변

0

서버에서 TLS를 예상하므로 일반 텍스트를 사용할 수 없습니다. 일반적으로 아무 것도 할 필요가 없습니다. 사용하는 TLS에 grpc - 자바 채널 기본값 :

ManagedChannel channel = OkHttpChannelBuilder.forAddress("127.0.0.1", 9111) 
    .sslSocketFactory(yourSslSocketFactory) 
    .build(); 

는 클라이언트가 서버의 인증서가 신뢰할 수있는 인증 기관 (CA)에 의해 서명되어야하기 때문에 서버를 식별하는 모든 파일을 필요로하지 않는다. 이것이 사실 인 경우 귀하의 질문에 의해 명확하지 않습니다. 자체 서명 된 인증서 또는 사용자 지정 CA를 사용하여 인증서에 서명하는 경우 grpc-okhttp가 기본적으로 사용하는 SSLSocketFactory.getDefault()은 서버의 인증서를 수락하지 않습니다. gRPC 사용할 수 있도록 그 드문 경우

, 당신은 SSLSocketFactory를 지정해야합니다 :

ManagedChannel channel = OkHttpChannelBuilder.forAddress("127.0.0.1", 9111) 
    .sslSocketFactory(yourSslSocketFactory) 
    .build(); 

을 당신은 바이너리 클라이언트의 인증서를 포함해야하고, yourSslSocketFactory은 그것의를 위해 해당 인증서를 참조해야합니다 TrustManager. 예 (some grpc tests에서 가져옴) :

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(null, null); 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
Certificate cert = cf.generateCertificate(theRawCert); 
ks.setCertificateEntry("customca", cert); 

TrustManagerFactory trustManagerFactory = 
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
trustManagerFactory.init(ks); 
SSLContext context = SSLContext.getInstance("TLS", provider); 
context.init(null, trustManagerFactory.getTrustManagers(), null); 
return context.getSocketFactory();