OpenSSL 4.0 迁移:ASN1_STRING 转 opaque、engines 移除,nginx/PHP 需重新编译
项目信息:
版本位置
OpenSSL 4.0.0 于 2026-04-14 发布。这是 feature release,不是 LTS:支持到 2027-05-14,比 LTS 分支 3.5(到 2030-04)短不少。4.1 计划在 2026-10 发布。
换句话说,如果生产环境跑的是 3.5 LTS,升级到 4.0 换来的是一年多的支持窗口和一批新特性,代价是下面这些不兼容变更。
迁移前要核对的不兼容变更
- ASN1_STRING 改为 opaque。不能再直接访问内部字段,所有依赖它的 ASN1 代码都要改。
- 大量 API 签名加了 const,集中在 X509 处理相关函数上,参数和返回值都有。典型例子:
X509_get_subject_name()在 3.x 返回X509_NAME *,4.0 返回const X509_NAME *。原来直接赋值给非 const 指针的代码会出 warning。 - 移除 engines 支持。
no-engine构建选项与OPENSSL_NO_ENGINE宏恒存在。 - 移除 SSLv3 支持,同时移除 SSLv2 Client Hello 支持。
- 废弃的 EC 曲线默认关闭,包括 RFC 8422 里列的那些,以及显式 EC 曲线。需要显式配置启用:
enable-tls-deprecated-ec/enable-ec_explicit_curves。 - 移除
c_rehash脚本,改用openssl rehash。 - 弃用
X509_cmp_time()、X509_cmp_current_time()、X509_cmp_timeframe(),改用X509_check_certificate_times()。 - libcrypto 不再通过
atexit()清理全局分配的数据。OPENSSL_cleanup()改为在全局析构中运行,或者默认根本不运行。 - 移除
ERR_get_state()、ERR_remove_state()、ERR_remove_thread_state(),ERR_STATE恒为 opaque。 - 十六进制密钥数据打印去掉了多余的前导
00:;签名 dump 宽度统一为 24 字节。 - 移除
openssl ca的 msie-hack 选项,移除BIO_f_reliable()实现。
打印输出改进
openssl s_client / s_server 现在通过新的 SSL_get0_sigalg() / SSL_get0_shared_sigalg() 报告 IANA 注册的签名算法名。原来的 SSL_get_sigalgs() 只适合 TLS 1.2,已被取代。
新增能力
- Encrypted Client Hello(ECH,RFC 9849)。
- RFC 8998 的
sm2sig_sm3、curveSM2,以及后量子混合组curveSM2MLKEM768。 - cSHAKE(SP 800-185)、ML-DSA-MU 摘要算法。
- SNMP KDF、SRTP KDF。
- FIPS 自测可延迟,用
openssl fipsinstall -defer_tests开启。 - TLS 1.2 协商 FFDHE 密钥交换(RFC 7919)。
安全补丁
4.0.2(2026-08-25)修了 QUIC 服务器处理 INITIAL 包的 double free、CMS 密钥解包的堆溢出等问题;4.0.1 有一个 High 级别修复。
运维提示
nginx、PHP、数据库等依赖 OpenSSL 的组件,在操作系统升级到 OpenSSL 4.0 之后需要重新编译适配。例如 nginx 1.29.8 / 1.30 就专门针对 X509_get_subject_name() 的返回值变化和 ASN1 接口做了适配。
升级前建议先在测试环境确认:调用 X509 相关 API 的模块是否有 const 赋值 warning、是否有代码在编译期依赖 engine、是否有脚本还在调用 c_rehash。