修复 git HTTPS 错误:macOS 12 上的“错误密钥长度”

Posted

技术标签:

【中文标题】修复 git HTTPS 错误:macOS 12 上的“错误密钥长度”【英文标题】:Fixing git HTTPS Error: "bad key length" on macOS 12 【发布时间】:2021-12-12 12:12:23 【问题描述】:

我正在使用可通过 HTTPS 访问的公司托管 (Bitbucket) git 存储库。访问它(例如git fetch)使用 macOS 11(Big Sur)工作,但在更新到 macOS 12 Monterey 后中断。 *

在将 macOS 更新到 12 Monterey 之后,我之前的 git 设置坏了。现在我收到以下错误消息:

$ git fetch
fatal: unable to access 'https://.../':
error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length

不管怎样,使用curl 也不起作用:

$ curl --insecure -L -v https://...
*   Trying ...
* Connected to ... (...) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length
* Closing connection 0
curl: (35) error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length

通过 Safari 或 Firefox 访问相同的 HTTPS 源是可行的。

据我了解,底层错误“bad key length”错误来自OpenSSL/LibreSSL,这与 git 和 curl 在操作系统升级后失败是一致的。

这是 openssl 的输出:

$ openssl s_client -servername ... -connect ...:443
CONNECTED(00000005)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
verify return:1
depth=0 ...
4593010348:error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length:
/System/Volumes/Data/SWE/macOS/BuildRoots/b8ff8433dc/Library/Caches/com.apple.xbs
/Sources/libressl/libressl-75/libressl-2.8/crypto/apple/hmac/hmac.c:188:
---
Certificate chain
 ...
---
No client certificate CA names sent
Server Temp Key: DH, 2048 bits
---
SSL handshake has read 4105 bytes and written 318 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-GCM-SHA384
    Session-ID: 1FA062DC9EEC9A310FF8231F1EB11A3BD6E0778F7AB6E98EAD1020A44CF1A407
    Session-ID-ctx:
    Master-Key:
    Start Time: 1635319904
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

我确实尝试将服务器的证书添加到自定义 pem 文件中并设置 http.sslCAInfo,但这不起作用。作为一种解决方法,我目前正在使用解密/重新加密 HTTPS 流量的代理。

如何配置 git(或所有 LibreSSL 用户)以接受服务器的证书?

【问题讨论】:

我不知道,但尽管出现错误消息,但至少 openssl s_client -servername ... -connect ...:443 实际上成功完成了 TLS 握手。如果只是为了尝试隔离问题,我会使用不同的最新版本的 openssl 再次尝试此操作。 @PresidentJamesK.Polk 作为罪魁祸首的 SSL 库与操作系统升级后出现的问题一致。但是,这也使得更改 SSL 库变得困难:如您所见,库本身位于 /Library/Caches 内部,即 dyld_shared_cache,这使得更改非常棘手 只有 LibreSSL(不是 OpenSSL)使用函数 FFF=CRYPTO_internal。尽管 OpenSSL 已经定义了这个原因很长一段时间,但 AFAICT 直到 1.1.1d(Libre 分叉之后)才使用它,然后仅用于 RC5(未在 SSL/TLS 中使用)。 Libre 确实将它用于 HMAC,如命令行中的错误详细信息所示,但路径 crypto/apple/hmac/ 表明 Apple 已以可能错误的方式对其进行了修改。它绝对与服务器证书无关。 eBuccaneer 的方法可能通过使用未由苹果修改的 brew 中的 openssl 来工作。 【参考方案1】:

很遗憾,我无法为您提供修复程序,但我找到了解决完全相同的问题的解决方法(公司托管的 bitbucket 导致完全相同的错误)。 我也不知道问题发生的确切原因,但我最好的猜测是 Monterey 附带的 libressl 库在特定 (?TLSv1.3) 证书方面存在某种问题。这种猜测是因为 brew 安装的 openssl v1.1 和 v3 在使用 /opt/homebrew/opt/openssl/bin/openssl s_client -connect ...:443 执行时不会抛出该错误

为了解决这个错误,我从针对不同 openssl 和 curl 实现的源代码构建了 git:

    用brew安装autoconfopensslcurl(我想你可以选择你喜欢的openssl库,即v1.1或v3,我选择v3) 克隆你喜欢的git版本,即git clone --branch v2.33.1 https://github.com/git/git.git cd git make configure(这就是需要 autoconf 的原因) 执行LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/curl/lib" CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/curl/include" ./configure --prefix=$HOME/git(这里LDFLAGS和CPPFLAGS包括git将构建的库,正确的标志由brew在curl和openssl安装成功时发出;--prefix是git的安装目录,默认为@987654329 @ 但可以更改) make install 确保将安装目录的子文件夹 /bin 添加到 $PATH 的前面,以“覆盖” Monterey 提供的默认 git 重启终端 检查git version 是否显示新版本

这现在应该有所帮助,但正如我已经说过的,这只是一种解决方法,希望 Apple 尽快修复他们的 libressl 分支。

【讨论】:

我宁愿不创建自定义的 git 构建,但是这可行,所以我接受该解决方案。但是,如果有人可以提供不需要这个的不同解决方案,我将不胜感激。 对于我公司的其他用户,我创建了一个自定义自制公式,与标准 git.gb 几乎 1:1 相同;唯一的区别是缺少瓶子和depends_on "curl" 而不是uses_from_macos "curl"【参考方案2】:

接受的答案有效,但您可能需要检查 lib 和包含路径是否正确

brew info openssl

brew info curl

【讨论】:

以上是关于修复 git HTTPS 错误:macOS 12 上的“错误密钥长度”的主要内容,如果未能解决你的问题,请参考以下文章

修复黑苹果安装macOS 12 intel网卡蓝牙驱动问题

由于macOS 10.12.3和10.12.5上缺少zlib,R无法安装devtools或git2r

在 Windows 中使用 gitstats 和 git 时如何修复错误

修复:AWS Bitnami LAMP 堆栈错误中的 Laravel Git 克隆

命令行工具 bash (git) 不起作用 - macOS Sierra 最终候选版本

苹果修复macOS 12.3.1 Monterey漏洞,但Big Sur/Catalina未修复