簡體   English   中英

grpc中的安全連接

[英]Secured connection in grpc

使用gRPC連接到服務器時出現問題。 服務器使用證書文件(rpc.cert和rpc.key)進行身份驗證,但我不知道如何包括這些文件。 目前這是我用來連接的代碼

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)

我找不到在android中使用grpc okhttp的任何文檔。 谷歌的gRPC文檔不包含該內容,所以我幾乎不知道該怎么辦。

由於服務器需要TLS,因此不能使用純文本。 通常,您不需要執行任何操作。 grpc-java頻道默認使用TLS:

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

客戶端不需要任何文件來標識服務器,因為服務器的證書應由受信任的證書頒發機構(CA)簽名。 您的問題尚不清楚,是否確實如此。 如果您使用自簽名證書或自定義CA對證書進行簽名,則grpc-okhttp默認使用SSLSocketFactory.getDefault()可能不會接受服務器的證書。

在這種罕見的情況下,您將需要指定SSLSocketFactory以便gRPC使用:

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

您需要在客戶端二進制文件中包括一個證書,而yourSslSocketFactory將需要為其TrustManager引用該證書。 例如(摘自一些grpc測試 ):

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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM