Android grpc 错误:TLS ALPN 协商失败,协议:[grpc-exp,h2]

Posted

技术标签:

【中文标题】Android grpc 错误:TLS ALPN 协商失败,协议:[grpc-exp,h2]【英文标题】:Android grpc error: TLS ALPN negotiation failed with protocols: [grpc-exp, h2] 【发布时间】:2020-04-28 12:37:51 【问题描述】:

我正在尝试在 android 应用中使用 grpc

代码的重要部分是这样的:

private val managedChannel: ManagedChannel = ManagedChannelBuilder
        .forTarget("misserverurl.com")
        .build()

带有版本和依赖的build.gradle:

minSdkVersion 19

implementation "io.grpc:grpc-okhttp:1.26.0"
implementation "io.grpc:grpc-protobuf:1.26.0"
implementation "io.grpc:grpc-stub:1.26.0"

protos 似乎没问题,并且应用程序在没有 TLS 的情况下也能正常工作 (.usePlaintext())

但我收到此错误:

java.lang.RuntimeException: TLS ALPN negotiation failed with protocols: [grpc-exp, h2]

SSL 握手似乎有问题。

奇怪的是服务器使用 BloomRCP 使用 TLS 工作。

我尝试了不同的 minSdkVersions,也使用了不同的 io.grpc.* lib 版本,并创建了一个空的 repo,其中只有 proto 文件和运行它的基本代码,但没有添加 .connectionSpec() 和不同的 CipherSuite 作为好吧。

使用 Wireshark 我可以看到我发送的 TLS 版本是 1.2,这是正确且符合预期的(也许它没有使用 HTTP2?)

有客人吗? 提前致谢!

----------------------------------------------- - - 编辑 - - - - - - - - - - - - - - - - - - - - - - - ------

查看我发现这个方法的库:useTransportSecurity()

/**
* Sets the negotiation type for the HTTP/2 connection to TLS (this is the default).
...
*/
@Override
public final OkHttpChannelBuilder useTransportSecurity()  ... 

我们默认使用带有 HTTP/2 的 TLS,所以这不是问题...

【问题讨论】:

【参考方案1】:

在 TLS 期间使用 ALPN 协商 HTTP/2。客户端发送它支持的协议(在本例中为 grpc-exp 和 h2,即 http/2)。然后服务器选择什么协议,或者没有。如果没有选择,那么唯一的选择是退回到另一个协议,例如 HTTP/1,或者失败。

gRPC 需要 HTTP/2,因此服务器必须通过 ALPN 选择“h2”。错误是那没有发生。您的服务器需要支持 HTTP/2。如果您使用 TLS 终结器或使用 L7 负载均衡器,则必须将其配置为支持 HTTP/2。

【讨论】:

但是有没有可能github.com/grpc/grpc-java 的默认配置是使用 TLS 不通过 HTTP/2 进行请求?如果是这种情况,我该如何设置?不确定 h2 是否是问题所在,但不知道为什么它接受 BloomRPC 请求但没有 GRPC-JAVA 【参考方案2】:

最后是后端问题。 在此之后:https://www.getambassador.io/reference/core/tls/#alpn_protocols alpn_protocol 是这样设置的:

alpn_protocol = h2[, grpc-epx]

它应该在哪里:

alpn_protocol = h2

有了这个和客户端的配置,它就起作用了!

private val managedChannel: ManagedChannel = ManagedChannelBuilder
        .forTarget("misserverurl.com")
        .build()

【讨论】:

【参考方案3】:

之前使用java 1.8.0_242-b08的时候遇到过这个问题,升级到1.8.0_265后没有问题

【讨论】:

以上是关于Android grpc 错误:TLS ALPN 协商失败,协议:[grpc-exp,h2]的主要内容,如果未能解决你的问题,请参考以下文章

异常 ALPN 配置不正确

gRPC - macOS missing ALPN support.

Python 2.7 中的 TLS ALPN

如何在 .NET C# 中为 HTTP/2 服务器实现 TLS-ALPN

为 SSL / TLS 配置 Proton 引发 openssl 错误版本号和 gRPC 客户端错误

HTTPS那些协议:TLS, SSL, SNI, ALPN, NPN