在Windows上使用自签名证书的git时出现“无法解析‘无法获取本地颁发者证书’”错误

652
我正在Windows系统上使用Git,安装了msysGit工具包。我的测试仓库在服务器上有自签名证书。我可以访问和使用HTTP协议的仓库而没有问题,但切换到HTTPS协议后会出现如下错误信息:
SSL证书问题:无法获取本地颁发者证书。
我已将自签名证书添加到Trusted Root Certification Authorities中,证书是安装在我的Windows 7客户机上的。在Internet Explorer中,我可以浏览HTTPS仓库的URL而不会出现错误消息。
根据Philip Kelley的这篇博客文章所述,cURL不使用客户端机器的证书存储。我按照博客文章中的建议创建了私人副本curl-ca-bundle.crt,并配置Git使用该副本。我确信Git正在使用我的副本。如果我重命名副本,Git就会报告找不到文件。
我像博客文章中提到的那样粘贴了我的证书,但仍然收到“无法获取本地颁发者证书”的消息。
我通过HTTPS克隆了一个GitHub代码库并验证了Git仍然可用。
我所看到的唯一不同于博客文章的地方是我的证书 根证书 - 没有链路可以到达它。我的证书最初来自于点击IIS8 IIS Manager链接“创建自签名证书”。也许这使得证书在某些方面与cURL预期的不同。
如何让Git/cURL接受自签名证书?

2
还要检查一下您的本地网络是否被允许将文件推送到Github仓库。可能存在防火墙或杀毒软件限制。 - shasi kanth
我在这里得到了最佳解决方案。 - Sandeep Sherpur
我在Azure Pipelines中遇到了这个错误。您可以在此帖子中找到解决方案。 - Rajesh Swarnkar
对我来说,当我在Linux上使用Homebrew安装Git时,我遇到了这个问题。将Git从Homebrew更改为apt软件包后,问题得到了解决。 - anuragp
显示剩余2条评论
34个回答

863

问题在于git默认使用“Linux”加密后端。

从Git for Windows 2.14开始,您现在可以配置Git使用内置的Windows网络层SChannel作为加密后端。这意味着它将使用Windows证书存储机制,您无需明确配置curl CA存储机制:https://msdn.microsoft.com/en-us/library/windows/desktop/aa380123(v=vs.85).aspx

只需执行:

git config --global http.sslbackend schannel

那应该会有所帮助。

使用schannel已经成为在Windows上安装Git的标准设置,如果可能的话,建议不再使用SSH来检出存储库,因为https更容易配置,并且不太可能被防火墙阻止,这意味着失败的几率较小。


10
请注意,这种解决方案可能会导致“git config --global http.sslCAInfo <my-server-self-signed-cert.pem>”无法正常工作。我已经配置了“http.sslCAInfo”来使用一个自签名证书来连接服务器,这是我执行例如“git clone https://github.com/Microsoft/vscode.git”时遇到“SSL证书问题:无法获取本地颁发者证书”的原因(可能与OP不同)。最后,我使用https://dev59.com/o2Ag5IYBdhLWcg3wM4db#47196562 (Ben P.P. Tung) 中的答案来调整我的sslCAInfo配置以针对我的git服务器进行解决。 - Johnny Wong
如果您正在寻找一种将证书包含到本地 GitHub 服务器的 Git 证书存储中的方法,请按照此解决方案进行操作。 - Rajesh Swarnkar
1
这个方法对我有效,我正在使用VS Code,公司安装了一些VPN软件来保护流量,这个解决方案解决了我的问题。谢谢。 - Gengjun Wu
在执行该命令后,我又遇到了一个错误:"... schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - 证书链由不受信任的授权机构颁发",因为 Git 存储库现在持有不受信任的证书。然后我使用了 git config --global http.sslVerify false 命令,这是不安全的。 - CoolMind
请注意生产力防火墙,它们可能会阻止设置实际更改。特别是在Windows系统中,请以管理员身份运行Git CMD。 - CAD bloke
在Visual Studio中,转到git设置,选择Git全局设置,并将加密网络提供程序选项更改为安全通道。 - undefined

478

打开Git Bash并运行该命令,如果您想完全禁用SSL验证。

git config --global http.sslVerify false

注意:此解决方案会使您容易受到中间人攻击的威胁。 因此,请尽快重新开启验证:

git config --global http.sslVerify true

137
这个答案通过允许中间人攻击来破坏 SSL 的安全性。其他答案已经解释了如何配置 git 来信任您所需要的特定证书。 - dsh
30
的确是个糟糕的回答,你甚至没有告诉他们要重新打开SSL。这就是安全漏洞发生的原因。 - user1971598
55
要禁用单个 Git 命令的 TLS/SSL 验证,请使用以下命令:git -c http.sslVerify=false clone https://domain.com/path/to/git - Maxim Suslov
6
下面已经提供了几种解决方案,我已经指出了它们的缺点。所以你可以自行选择哪些解决方案来解决这个问题。 - Samir
6
这可能是一个权宜之计,但绝非解决方案。而且最好不要完全绕过所有 SSL 验证。你可以使用 git config --local http.sslVerify false 命令。这样只有一个仓库会变得不安全。 - mnieto
显示剩余6条评论

99

我也遇到了这个问题。在我的情况下,我试图让 post-receive Git hook 在每次 push 时更新服务器上的工作副本。试着按照你提供的博客中的说明操作,但是对我来说并没有起作用,而且覆盖每个用户的设置似乎也不起作用。

我最终不得不禁用 Git 的 SSL 验证 (如文章中所述) 。这不是完美的解决方案,但在我找到更好的解决方案之前可以使用。

我编辑了 Git 配置文本文件(使用像 Notepad++ 这样的喜爱换行符中性应用程序),该文件位于:

C:\Program Files (x86)\Git\etc\gitconfig

在 [http] 块中,我添加了一个选项以禁用 sslVerify。完成后,它看起来像这样:

[http]
    sslVerify = false
    sslCAinfo = /bin/curl-ca-bundle.crt

搞定了。

注意:

  • 这将禁用SSL验证,不建议作为长期解决方案。

  • 您可以对每个仓库禁用此设置,但这仍然不是一个好的解决方案,只是让设置局限于本地。

  • 随着LetsEncrypt.org的出现,现在可以相对简单、自动和免费地设置SSL来替代自签名证书,并避免关闭sslVerify的需要。


172
这会使 SSL 失去意义。 - syaz
53
您可以使用命令"git config --global http.sslVerify false"来禁用SSL验证。 - CleanCoder
9
感谢您指出 sslCAinfo 配置项;但我不会点赞该回答,因为永久禁用 git 系统范围内的 SSL 并不是一个很合理的做法(您尝试过在系统范围内禁用它,然后克隆代码,再重新启用它并在新克隆的仓库中禁用它吗?)。 - 7heo.tk
43
对于单次命令,无需更改配置文件:git -c http.sslVerify=false clone https://... - pts
@syaz 是的,当你必须使用由不知道自己在做什么的管理员管理的服务器并且必须访问该服务器上的 repos 时,这是必需的,并且在所有连接中禁用了端口22,甚至是他们自己无法保护的服务器,显然也是如此。 - Spencer Williams
9
改进方法在这里: https://blogs.msdn.microsoft.com/phkelley/2014/01/20/adding-a-corporate-or-self-signed-certificate-authority-to-git-exes-store/ - Warren P

74
kiddailey 的说法基本正确,不过我不会禁用 SSL 验证,而是提供本地证书:
在 Git 配置文件中:
[http]
    sslCAinfo = /bin/curl-ca-bundle.crt

或通过命令行:

git config --global http.sslCAinfo /bin/curl-ca-bundle.crt

13
在 Windows 版本的 Git 上,这个命令是 git config --global http.sslCAinfo /usr/ssl/certs/ca-bundle.crt - Karsten Tinnefeld
3
对我来说,git config --global http.sslCAinfo /c/Program\ Files\ \(x86\)/Git/bin/curl-ca-bundle.crt 的意思是设置 Git 使用指定路径下的 SSL 证书文件。 - sparrowt
对于使用MacPorts的用户,可以执行以下命令:git config --global http.sslCAinfo /opt/local/share/curl/curl-ca-bundle.crt - miken32
4
使用 Git 2.8 版本,您可以使用 git config --list --show-origin 命令查看 http.sslCAinfo 配置的设置位置。 - Anish
我的证书位置在Mac上是:~/macports/share/curl/curl-ca-bundle.crt。 - user3282611
我建议不要更改git证书存储。更好的方法是使用命令git config --list --show-scope查找git证书存储的位置,然后在该文件中添加您的证书。请参考此帖子 - Rajesh Swarnkar

64

我也遇到了这个问题。最终通过参考这篇MSDN博客得以解决。

更新

实际上,您需要将证书添加到位于Git\bin目录中的curl-ca-bundle.crt文件中。

步骤

  1. 在浏览器中打开您的github页面,并单击地址栏中的锁图标。
  2. 在弹出的小窗口中导航到“查看证书”链接,它会打开一个弹出窗口。
  3. 在其中导航到证书选项卡(在我的情况下是第三个)。选择顶级节点即根证书。然后在底部按下复制证书按钮并保存文件。
  4. 在文件浏览器中导航到Git\bin目录,并在文本编辑器中打开curl-ca-bundle.crt。
  5. 同样,在文本编辑器中打开导出的证书文件(第3步)。
  6. 将导出证书的所有内容复制到curl-ca-bundle.crt的末尾,并保存。

最后检查状态。请注意,在编辑之前备份curl-ca-bundle.crt文件以保险起见。


5
请进入Git\bin目录并打开curl-ca-bundle.crt文件。但是在git\bin目录中找不到curl-ca-bundle.crt文件。 - Anton K
1
@AntonK 如果不存在,请在记事本中创建一个,并将其重命名为curl-ca-bundle.crt。其他步骤保持不变。 - Nadeem Jamali
22
它可能被称为 ca-bundle.crt,并位于 mingw64\ssl\certsmingw32\ssl\certs 中。 - Ian Kemp
2
在Atlassian的SourceTree中使用此功能。捆绑的GIT安装位于%userprofile%\appdata\local\attlassian\sourcetree\git_local。curl-ca-bundle.crt已经存在,我附加了我的base64编码导出的根证书。 - Xanothos
1
这个答案存在一个问题。当你更新 git 时,它会将 ca-bundle.crt 文件恢复到原始状态(即你会失去自签名的公共证书)。 - John Rocha
1
链接返回403错误。 - Itération 122442

48

使用makecert创建开发SSL的一个答案解决了我的问题。

我不知道为什么,但是在IIS管理器中简单使用“创建自签名证书”链接生成的证书无法起作用。我遵循了链接问题中的方法,创建并安装了自签名CA根证书,然后使用该证书为我的服务器颁发了一个服务器认证证书。我在IIS中安装了它们两个。

这使得我的情况与原始问题中引用的博客文章相同。一旦将根证书复制/粘贴到curl-ca-bundle.crt中,git/curl组合就满足了要求。


我不知道为什么,但是在IIS管理器中简单的“创建自签名证书”链接创建的证书似乎行不通...据我所知,它会创建格式错误的证书。在创建X.509证书时有很多规则;“尽可能做最少的工作使其正常工作”的方法已经不再奏效。还可以参见如何使用您的认证机构签署证书签名请求如何使用openssl创建自签名证书? - jww
这对我有用,但是我在“我在IIS中安装了它们两个”部分暂时卡住了。为了让其他人更清楚...服务器证书在IIS中分配,并且根CA需要通过Windows证书管理器实用程序(certmgr.msc)导入到“受信任的根证书颁发机构”。 - Philip

39

在安装 Git-on-windows 时,在处理 Github 代码仓库(或任何非自签名证书) 时,选择以下选项解决了问题。

输入图像描述


2
你似乎回答了一个不同的问题。OP的问题涉及Windows客户端上的自签名证书。 - jww
1
@jww,这个问题的标题是一个Git错误消息,即使存储库没有自签名SSL也会显示! - Jawad Al Shaikh
这让我通过了错误,但是对于我来说,访问GitHub企业需要一些密钥生成和添加公钥/私钥。 - ΩmegaMan
2
如果自签名证书已通过组策略被一个友好的Windows管理员放入Windows证书存储,则此答案也是一个不错的选择。 - JamesD
2
这个解决方案比折腾SSL或手动添加证书要好得多。简单易行的解决方案!(我是开发人员,不是系统管理员。我不想被证书之类的东西困扰) - Hneel

36

为避免完全禁用 SSL 验证或复制 / 破解 Git 使用的捆绑 CA 证书文件,您可以将主机的证书链导出到文件中,并使 Git 使用它:

git config --global http.https://the.host.com/.sslCAInfo c:/users/me/the.host.com.cer

如果那不起作用,您可以仅为主机禁用SSL验证:

git config --global http.https://the.host.com/.sslVerify false

注意:当关闭ssl验证时,可能会遭受中间人攻击。


6
值得注意的是,“--global”选项并非必需。如果省略“--global”,则该设置仅适用于特定的Git存储库。 - Wes Turner
1
如果这是我的企业 Github 呢?我如何获取以 .cer 格式呈现的根证书和中间证书。我只能获得 .p7b 文件。 - Rajesh Swarnkar

29
为了完整详细地总结上述所有答案: 原因:此问题发生的原因是git无法与存储要访问的仓库的git服务器完成https握手。 解决方案:以下是从github服务器获取证书和将证书添加到本地git证书库的步骤: 步骤1:在浏览器中打开你想要访问的github网站。 步骤2:单击地址栏中的锁图标,然后单击“证书”。 步骤3:跳转到“证书路径”选项卡,选择证书层级结构中最顶部的节点,单击“查看证书”。 步骤4:现在单击“详细信息”,然后单击“复制到文件……”,单击“下一步”,选择“Base 64编码X509(.CER)”格式并保存到所需路径。 步骤5:现在打开保存的证书文件,将内容与"--Begin Certificate--" 和 "--end certificate--"一起复制到剪贴板。 步骤6:在命令提示符中执行以下命令来找到git存储所有证书的路径: git config --list 步骤7:检查密钥“http.sslcainfo”的值,对应的值将是路径。 注意:如果无法找到密钥http.sslcainfo,则检查Git的默认路径:C:\Program Files\Git\mingw64\ssl\certs。 步骤8:打开该路径下的“ca-bundle.crt”文件。 注意1:以管理员模式打开此文件,否则您将无法在更新后保存它。(提示-您可以使用Notepad++进行此操作)
注意2:在修改此文件之前,请在其他地方备份。
5. 现在将步骤1中提到的文件内容复制到步骤4中的文件末尾,就像其他证书被放置在ca-bundle.crt中一样。
6. 现在打开一个新终端,您应该能够使用https执行与git服务器相关的操作。

1
这似乎在公司防火墙的情况下无法工作。 - isherwood

25

我刚遇到了同样的问题,但是在Windows上使用Sourcetree。正常情况下,在Windows上使用git也是一样的。按照以下步骤,我成功解决了此问题:

  1. 获取服务器证书链 这可以通过Chrome完成。 导航到服务器地址。 单击挂锁图标并查看证书。 将所有证书链导出为Base64编码文件(PEM格式)。
  2. 将证书添加到GIT信任配置文件的信任链中。 运行“git config --list”。 找到“http.sslcainfo”配置,这显示证书信任文件的位置。 将所有证书复制到信任链文件中,包括"- -BEGIN- -"和"- -END- -"。
  3. 确保在证书文件中添加整个证书链

这样应该就可以解决使用自签名证书并使用GIT时遇到的问题。

我尝试使用“http.sslcapath”配置,但这并没有奏效。而且,如果未在证书文件中包含整个证书链,则也会失败。如果有关此方面的指针,请让我知道,因为必须为新安装重复上述过程。

如果这是系统GIT,则可以使用TOOLS->选项GIt选项卡中的选项来使用系统GIT,这样也可以解决Sourcetree中的问题。


2
如果我在证书文件中没有包含整个链,那么这也会失败 - 我刚遇到了这个问题。 - Amani Kilumanga
关于包含整个证书链,我拥有两个比github证书更高级的证书。我应该按照根证书->下一个证书->github证书的顺序将它们包含在sslcainfo.crt文件中吗? - Jecoms
我只需添加根证书就能访问git仓库包。 - Jecoms
为了未来的读者。不知道是否重要,但我将“根”(最顶层)证书放在了(http.sslcainfo)文件的末尾。然后,当我远离证书链中的根证书时,我将该证书放在了(http.sslcainfo)文件的前一个条目之上。 - granadaCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接