Node.js Web 项目报错 error:0308010C:digital envelope routines::unsupported 的解决方案

SerinaNya

0x01 什么情况下会出现这种问题?

根据 Node.js 官网的博客所写:
Node.js v17.x、v18.x 和 v19.x 使用 OpenSSL v3,而 v14.x 和 v16.x 不会受到影响。

OpenSSL November Security Release , by Rafael Gonzaga, 2022-10-28, nodejs.org

The OpenSSL project announced will release OpenSSL 3.0.7 on the 1th of November 2022 between 1300-1700 UTC. The release will fix security defects on which the highest severity issue is HIGH.
Node.js v17.x, v18.x, and v19.x use OpenSSL v3.
…
Node.js 14.x and v16.x are not affected by this OpenSSL update.

如果你遇到了这个问题,那你一定是使用了 OpenSSL v3 的 Node.js 版本。

此外,这个问题通常出现在 Web(前端)项目中,因此我将着重围绕着 Web(前端)项目来讲解。

0x02 报错是什么样的?

简单举几个例子,你可能会看到如下内容:

1
2
3
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:71:19)
at Object.createHash (node:crypto:133:10)
1
2
3
4
5
6
{
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
1
2
3
node:internal/crypto/hash:71
this[kHandle] = new _Hash(algorithm, xofLen);
^

0x03 解决方案

安全最重要(推荐)

👍这个问题是由 Node.js 的更新导致的,而更新的目的是为了修复高风险漏洞,对于重视安全的开发者来说,这个方案是 首 选 的 。

不少的前端项目都会使用到 webpack,如果你在使用 webpack 时遇到了这个问题,请尝试以下方案解决:

webpack v4

向 webpack 传递参数 output.hashFunction = 'sha512' 或 output.hashFunction = 'sha256',这将取决于你系统中 Node.js 支持哪些 Hash 算法。

webpack 官方文档给出的示例类似于下面这样:

output.hashFunction, webpack.js.org

1
2
3
4
5
6
module.exports = {
//...
output: {
hashFunction: 'sha512',
},
};

再举个 Vue.js 的例子,编辑 vue.config.js(在项目根目录下,如不存在请创建):

1
2
3
4
5
6
module.exports = {
//...
configureWebpack: {
output: { hashFunction: 'sha512' },
},
};

webpack v5.54.0+

从 webpack v5.54.0+ 开始,hashFunction 支持 xxhash64 作为一种更快的算法,当 experiments.futureDefaults 被启用时,它将被作为默认算法使用。

如果你的 webpack 版本低于 v5.54.0,请按上方 webpack v4 的步骤操作。

如果你满足 webpack v5.54.0+ 的条件,参照上方 webpack v4 的方法,将 sha512 或 sha256 替换为 xxhash64 即可。

能跑起来就行

⚠️注意:这可能导致你使用的 OpenSSL 存在漏洞,导致安全问题,只能浅浅使用!

为了安全务必确保 你和代码至少有一个能跑!

临时环境变量大法(通用)

这个解决办法是 通用 的!这意味着无论你是否编写的是前端项目,都可以使用这个方法,这将对 Node.js 直接生效。

运行代码前,在终端内添加环境变量 NODE_OPTIONS=--openssl-legacy-provider

macOS 和 Linux

1
export NODE_OPTIONS=--openssl-legacy-provider

Windows PowerShell

1
$env:NODE_OPTIONS = "--openssl-legacy-provider"

Windows 命令提示符(cmd)

1
set NODE_OPTIONS=--openssl-legacy-provider

为 Windows 设置全局环境变量

👇 这个方法对 Windows 系统来说简直就是万金油,99% 解决问题 👇

Win+R 打开 运行,输入 sysdm.cpl 后回车,选择 高级 选项,点击右下角 环境变量,点击 用户变量 中的 新建,变量名 为 NODE_OPTIONS,变量值 为 --openssl-legacy-provider。随后一直 确定 即可。

为 React 项目添加命令行参数

修改 packages.json 中 scripts 的一些字段:

1
2
3
4
5
6
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"build": "react-scripts --openssl-legacy-provider build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},

终极方案:降版本

装个低版本的没受到影响的 Node.js 不就好了 😅

比如 Node.js v16.x 就是不错的选择。如果你不知道去哪里下载,你可以去 Node.js Release - v16.x 看看。对于 Windows 用户,点击链接后可以看到高亮部分,下载它并安装即可。

对于 nvm 用户来说,切换 Node.js 版本只需要一行命令即可:

1
nvm install 16

nvm: Node Version Manager,如果你也想在多个 Node.js 版本之间快速切换,不妨了解一下 nvm 是否适合你。它可在 Windows 和 Linux, macOS, WSL 等系统上运行。

  • 标题: Node.js Web 项目报错 error:0308010C:digital envelope routines::unsupported 的解决方案
  • 作者: SerinaNya
  • 创建于 : 2023-01-15 20:00:00
  • 更新于 : 2023-01-15 20:00:00
  • 链接: https://serinanya.cn/2023/nodejs-digital-envelope-routines-unsupported/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。