You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK8编译JDK11运行时BouncyCastle ALPN协商失败问题咨询

问题说明

现有配置

  • JDK安全提供者注册代码:
Security.addProvider(new BouncyCastleFipsProvider())
  • gRPC客户端SSL上下文构建代码:
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient()
                    .sslProvider(SslProvider.JDK)
                    .applicationProtocolConfig(new ApplicationProtocolConfig(
                            ApplicationProtocolConfig.Protocol.ALPN, 
                            ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
                            ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
                            Collections.singletonList("h2")));
  • 环境版本信息:
    • gRPC版本:1.44(升级至1.46后问题仍存在)
    • bc-fips.jar版本:1.0.2
    • 编译JDK版本:JDK 1.8.0_291
    • 运行JDK版本:Java 11.0.15

异常现象

SSL握手完成后抛出如下错误:

UNAVAILABLE: Failed ALPN negotiation: Unable to find compatible protocol
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0]

初步排查结果

已确认根因指向BouncyCastleFipsProvider的SSLParametersUtil类存在逻辑缺陷,会异常移除ALPN建议协议列表中的h2协议,升级gRPC版本无法修复该问题。


解决方案

按落地成本从低到高排序,可选择以下任意一种方案修复:

  • 禁用BC FIPS的JSSE实现/调整注册优先级
    问题触发的核心原因是BC FIPS 1.0.2版本的JSSE实现接管了SSL参数处理逻辑,存在ALPN协议过滤bug。两种调整方式都可解决:
    1. 追加JVM启动参数-Dorg.bouncycastle.fips.jsse.enable=false,禁用BC FIPS自带的JSSE实现,仅保留其提供的各类加密算法能力,SSL/TLS逻辑继续由JDK原生JSSE处理,无需修改业务代码。
    2. 若通过代码调整,不要将BC FIPS注册为最高优先级(位置1)的安全提供者,将其放在JDK原生JSSE提供者序列之后即可,避免BC的SSL逻辑被优先加载。
  • 升级bc-fips版本到1.0.2.3及以上
    1.0.2版本的bc-fips存在已知ALPN处理bug:逻辑中错误过滤了长度小于3字节的ALPN协议名,而h2长度为2字节,因此被意外移除。1.0.2.3及以上版本已经修复该判断逻辑,升级后无需调整其他配置即可正常协商h2协议。
  • 切换SSL提供者为OPENSSL
    若环境可引入netty-tcnative本地依赖,可将SSL实现从JDK切换为OpenSSL,完全绕过JDK层安全提供者的ALPN处理逻辑,同时能获得更好的SSL性能。修改SSL上下文配置:
    SslContextBuilder sslContextBuilder = SslContextBuilder.forClient()
                        .sslProvider(SslProvider.OPENSSL)
                        .applicationProtocolConfig(new ApplicationProtocolConfig(
                                ApplicationProtocolConfig.Protocol.ALPN, 
                                ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
                                ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
                                Collections.singletonList("h2")));
    
    该方案需要确保部署环境的系统架构、glibc版本与引入的netty-tcnative二进制包匹配。
  • 强制覆写SSLEngine的ALPN参数(临时规避)
    若暂时无法升级依赖、也无法调整BC配置,可添加SSL引擎定制器,在SSLEngine初始化完成后强制写入正确的ALPN协议列表,绕过BC的参数过滤逻辑:
    sslContextBuilder.sslEngineConfigurator(sslEngine -> {
        SSLParameters params = sslEngine.getSSLParameters();
        params.setApplicationProtocols(new String[]{"h2"});
        sslEngine.setSSLParameters(params);
        return sslEngine;
    });
    

内容的提问来源于stack exchange,提问作者yatir dagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 13:03:30