描述错误
我使用 HTTPS=true
、 SSL_CRT_FILE=/cert/server.crt
和 SSL_KEY_FILE=/cert/server.key
环境变量创建了最简单的设置。当运行 npm start
时,我遇到了以下错误:
The certificate "/cert/server.crt" is invalid.
error:0608B096:digital envelope routines:EVP_PKEY_encrypt_init:operation not supported for this keytype
证书有效且在许多项目中被积极使用。唯一的区别是它们是 ECC 密钥。可以使用以下命令生成类似的密钥:./acme.sh --issue -k ec-384 -ak 4096 --dns dns_cf -d dev.example.com -d example.com --home /cert
你尝试恢复依赖项了吗?
这是一个全新的项目。
npm --version
7.6.1
你在用户指南中搜索了哪些术语?
https、椭圆曲线、证书等。
环境
主机正在运行最新的 Debian 10 (Buster) 和 Docker v20.10.5,带有官方 Node 容器。在容器内运行的命令:
Environment Info:
current version of create-react-app: 4.0.3
running from /root/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app
System:
OS: Linux 4.19 Debian GNU/Linux 9 (stretch) 9 (stretch)
CPU: (4) x64 Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz
Binaries:
Node: 15.11.0 - /usr/local/bin/node
Yarn: 1.22.5 - /usr/local/bin/yarn
npm: 7.6.1 - /usr/local/bin/npm
Browsers:
Chrome: Not Found
Firefox: Not Found
npmPackages:
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
react-scripts: 4.0.3 => 4.0.3
npmGlobalPackages:
create-react-app: Not Found
重现步骤
- 使用上述 acme.sh 获取免费的 ECC 证书,并将其放置在
/cert
npx create-react-app my-app
- 设置环境变量
HTTPS=true
、SSL_CRT_FILE=/cert/server.crt
和SSL_KEY_FILE=/cert/server.key
npm start
预期行为
我应该看到登录页面,而不是错误。如果我取消定义环境变量 HTTPS
并将地址更改为 http:// 而不是 https://,它就可以正常工作。
实际行为
立即终止,并出现以下错误:
The certificate "/cert/server.crt" is invalid.
error:0608B096:digital envelope routines:EVP_PKEY_encrypt_init:operation not supported for this keytype
可复现的演示
我认为这是最简单的事情了,除了获取 Lets Encrypt 证书之外。如果有必要,我可以创建一个仓库。
3条答案
按热度按时间q1qsirdb1#
这是因为CRA通过加密文本然后解密来验证密钥,而ECC算法不支持这些功能(据我所知)。
现在,大多数情况下推荐使用ECC密钥而不是RSA密钥,因为它们在带宽和计算需求方面都更优越。
我不知道是否有一个同样简单易行的方法来验证ECC密钥,就像
validateKeyAndCerts
目前所做的那样。如果没有,我建议以下几种方法:validateKeyAndCerts
检查;validateKeyAndCerts
;validateKeyAndCerts
抛出异常,向用户提供控制台警告,但允许进程继续进行j5fpnvbx2#
ECC密钥确实支持加密/解密(在上面的示例中分别使用
server.key
和server.crt
),这是它们作为非对称密钥的全部目的。不过我喜欢你的建议。实际上,我不确定为什么甚至需要一个证书验证步骤。为什么不让错误的证书像其他人一样浮出到浏览器?我是不是漏掉了什么?ss2ws0br3#
我的意思是,OpenSSL只支持几种ECC算法——密钥协商和签名/验证——参见here。这就是为什么
crypto.publicEncrypt
失败的原因。无论如何,我同意你的观点。整个
validateKeyAndCerts
步骤感觉是不必要的。