快速修复
# 一键:临时兼容——启用 legacy provider 让 OpenSSL 重新提供 MD4
NODE_OPTIONS=--openssl-legacy-provider npm run build
只作过渡;长期请升级构建工具。
你会遇到什么
用新版本 Node 跑旧项目(webpack 4 系,如老 create-react-app / vue-cli 项目)时,构建/启动即报 Error: error:0308010C:digital envelope routines::unsupported。
报错前 0 秒、无任何业务代码改动;切到项目要求的低版本 Node(如 16.15.0)就正常。不是项目代码的问题,是「老构建工具 + 新运行时」的兼容断层。
本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。
为什么会这样
Node ≥17 链接的是 OpenSSL 3,而 OpenSSL 3 把 MD4 移到了 legacy provider(默认不加载);webpack <5 默认用 crypto.createHash('md4') 做模块/chunk 哈希,调用时直接抛 digital envelope routines::unsupported。升级 Node 大版本后最容易撞上。
digital envelope routines::unsupported 是 OpenSSL 3 的 provider 机制:OpenSSL 3 把 MD4/MD5 等弱算法移进 legacy provider,默认不加载;
Node ≥17 链接 OpenSSL 3,而 webpack <5 用 crypto.createHash('md4') 做模块/chunk 哈希——算法在默认 provider 里不存在,调用即抛错。这不是业务代码的 bug,是「工具链版本组合」问题:Node 大版本升级后,底层 OpenSSL 变了,旧构建工具的行为就变了。
确定性推论:升级 Node 后老项目构建报此错 = 先查构建器是否用了 md4(webpack 配置 output.hashFunction);两条正路——升级 webpack(≥5 默认用更安全的算法)或显式指定 output.hashFunction: 'sha256'(webpack <5 可用);
NODE_OPTIONS=--openssl-legacy-provider 是「重新加载 legacy provider」的临时逃生门,能过但弱算法回归,只用于没法升级的存量项目;判断路径:报错栈里出现 createHash/md4 即坐实。
一步步来
1. 长期正解:升级构建工具 — 必做
webpack 升级到 ≥5(5.61+ 自带 wasm 哈希回退,不再依赖 OpenSSL MD4);create-react-app/vue-cli 项目跟随官方升级脚本(npm i -D webpack@5 / npx create-react-app@latest 等)。
2. 临时兼容(最快见效) — 必做
NODE_OPTIONS=--openssl-legacy-provider npm run build
或写入 .env(老 CRA 项目会读取):echo NODE_OPTIONS=--openssl-legacy-provider >> .env。注意:Node 17.0–17.2 的 NODE_OPTIONS 不允许该开关,用命令行参数 node --openssl-legacy-provider 或换 Node 版本。legacy provider 安全性弱于默认,只作过渡。
3. 换 Node 版本(文章方案) — 必做
nvm use 16.15.0
切到项目锁定的旧版本后正常——治标,掩盖了"工具链过旧"的根因,长期仍建议升级。
怎么确认修好了
md4 可用(实测输出形态):
NODE_OPTIONS=--openssl-legacy-provider node -e "crypto.createHash('md4').update('x').digest('hex')" → 输出摘要 866437cb...(实测)
对照组:默认配置 createHash('md4') → error:0308010C(实测复现,堆栈与文章逐字一致);createHash('sha256') 正常(md4 专属问题)。
其它环境的表现
| 环境 | 说明 |
|---|---|
| Node ≥17 + OpenSSL 3 | md4 在 legacy provider,默认不可用 |
| webpack <5 | 用 md4 做哈希,必撞 |
| webpack ≥5.61 | wasm 哈希回退,无需处理 |
| Node 17.0–17.2 | NODE_OPTIONS 不允许该开关,用命令行参数 |
| 换 Node 版本 | nvm use 旧版本,治标 |
症状
用新版本 Node 跑旧项目(webpack 4 系,如老 create-react-app / vue-cli 项目)时,构建/启动即报:
ERROR Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:101:19)
at Object.createHash (node:crypto:139:10)
典型场景:本机 Node 22.x 跑项目,报错前 0 秒、无任何业务代码改动;切到项目要求的低版本 Node(如 16.15.0)就正常。
原因
Node ≥17 链接的是 OpenSSL 3,而 OpenSSL 3 把 MD4 移到了 legacy provider(默认不加载);webpack <5 默认用 crypto.createHash('md4') 做模块/chunk 哈希,调用时直接抛 digital envelope routines::unsupported。这不是项目代码的问题,是「老构建工具 + 新运行时」的兼容断层(升级 Node 大版本后最容易撞上)。
解法
按推荐顺序选:
- 长期正解:升级构建工具 —— webpack 升级到 ≥5(5.61+ 自带 wasm 哈希回退,不再依赖 OpenSSL MD4);create-react-app/vue-cli 项目跟随官方升级脚本(
npm i -D webpack@5/npx create-react-app@latest等)。 - 临时兼容(最快见效):启用 legacy provider,让 OpenSSL 重新提供 MD4:
# 单次命令
NODE_OPTIONS=--openssl-legacy-provider npm run build
# 或写入 .env(老 CRA 项目会读取)
echo NODE_OPTIONS=--openssl-legacy-provider >> .env
注意:Node 17.0–17.2 的 NODE_OPTIONS 不允许该开关,用命令行参数 node --openssl-legacy-provider 或换 Node 版本。legacy provider 安全性弱于默认,只作过渡。
- 换 Node 版本(文章方案):nvm 切到项目锁定的旧版本(如
nvm use 16.15.0)后正常——治标,掩盖了「工具链过旧」的根因,长期仍建议升级。
验证证据
- 本地实测(2026-08-29,Node v22.22.1 / npm 9.2.0 / OpenSSL 3.5.5,与文章报错环境同代):
node -e "crypto.createHash('md4')..."→ 完整复现error:0308010C:digital envelope routines::unsupported,堆栈与文章逐字一致(new Hash (node:internal/crypto/hash:101:19));- 对照组:同一进程
createHash('sha256')正常输出摘要 —— 证明是 md4 专属问题,不是 crypto 全挂; NODE_OPTIONS=--openssl-legacy-provider node ...与node --openssl-legacy-provider ...→ md4 均成功输出摘要866437cb...(两种传法都验证);openssl version= 3.5.5,openssl list -digest-algorithms中 MD4 仅在 legacy 条目(RSA-MD4 => MD4)——佐证「默认 provider 不含 md4」。- 实测复现日志(2026-08-29)
适用工具 (2)
本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。
node · 外部工具npm · 外部工具来源与证据
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡