Skip to content

Node.js OpenSSL 错误:error:0308010C 解决方案

问题描述

在使用 Node.js(特别是 v17+ 版本)运行项目时,可能会遇到以下错误:

bash
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)
    at module.exports (/app/node_modules/webpack/lib/util/createHash.js:135:53)
    ...
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'

这个错误通常发生在构建或者启动 React、Next.js、Angular 等前端项目时,特别是在 Docker 容器环境中。

根本原因

该问题的根本原因是 Node.js 版本兼容性问题:

  1. OpenSSL 版本变更:Node.js v17.0.0 开始使用 OpenSSL 3.0
  2. 算法支持变化:OpenSSL 3.0 默认禁用了 MD4 等较旧的加密算法
  3. 依赖冲突:Webpack 4 及更早版本仍然依赖这些被禁用的算法进行哈希计算

安全提醒

使用 --openssl-legacy-provider 只是临时解决方案,因为旧的加密算法存在安全漏洞。建议最终解决方案是升级项目依赖。

解决方案

方法一:设置环境变量(推荐临时解决方案)

在不同环境中设置 NODE_OPTIONS 环境变量:

bash
export NODE_OPTIONS=--openssl-legacy-provider
bash
set NODE_OPTIONS=--openssl-legacy-provider
bash
$env:NODE_OPTIONS = "--openssl-legacy-provider"
dockerfile
FROM node:18-alpine
ENV NODE_OPTIONS="--openssl-legacy-provider"
# 其余配置保持不变...

方法二:修改 package.json 脚本

根据你的项目类型修改启动脚本:

json
{
  "scripts": {
    "start": "react-scripts --openssl-legacy-provider start",
    "build": "react-scripts --openssl-legacy-provider build"
  }
}
json
{
  "scripts": {
    "dev": "node --openssl-legacy-provider ./node_modules/.bin/next dev",
    "start": "node --openssl-legacy-provider ./node_modules/.bin/next start",
    "build": "node --openssl-legacy-provider ./node_modules/.bin/next build"
  }
}

方法三:降级 Node.js 版本

如果项目允许,降级到 Node.js v16:

bash
# 使用 nvm 切换 Node.js 版本
nvm install 16
nvm use 16

对于 Docker 项目,修改基础镜像版本:

dockerfile
FROM node:16-alpine  # 使用 Node.js 16 而不是 18

方法四:更新项目依赖

长期解决方案是更新项目依赖以兼容新版本 Node.js:

bash
# 更新 npm 包
npm update

# 或者使用 yarn
yarn update

各场景下的解决方案

Docker 环境

修改 Dockerfile 添加环境变量:

dockerfile
FROM node:18-alpine
ENV NODE_OPTIONS="--openssl-legacy-provider"
EXPOSE 3000
WORKDIR /app
COPY ./frontend/package.json .
RUN npm install
COPY ./frontend .
COPY ./images .
CMD ["npm", "start"]

Heroku 部署

在 Heroku 设置中添加环境变量:

  • Key: NODE_OPTIONS
  • Value: --openssl-legacy-provider

持续集成/持续部署 (CI/CD)

在构建脚本中添加环境变量设置:

yaml
# GitHub Actions 示例
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Set environment variable
        run: echo "NODE_OPTIONS=--openssl-legacy-provider" >> $GITHUB_ENV
      - name: Install and build
        run: |
          npm install
          npm run build

预防措施

  1. 定期更新依赖:保持项目依赖更新以避免兼容性问题
  2. 版本兼容性检查:在升级 Node.js 前检查项目依赖的兼容性
  3. 使用 Node.js LTS 版本:生产环境尽量使用长期支持版本
  4. Docker 多阶段构建:使用适当的基础镜像版本

总结

error:0308010C:digital envelope routines::unsupported 错误是由于 Node.js v17+ 使用 OpenSSL 3.0 导致的兼容性问题。虽然可以通过设置 --openssl-legacy-provider 标志临时解决,但最佳实践是更新项目依赖以确保长期兼容性和安全性。

建议

对于新项目,建议直接使用最新的 Webpack 5 和现代前端工具链,它们已经适配了 OpenSSL 3.0,无需使用遗留提供程序。

通过上述方法,你应该能够解决这个错误并顺利运行或构建你的项目。