macOS Git 客户端可以使用存储在用户钥匙串中的证书吗?

Can the macOS Git client use certificates stored in the user's Keychain?

我们的 Git 服务器正在更改为在 Git 客户端访问时需要 certificate/private 密钥。

我们的 Windows 用户被指示在本地导入证书,然后配置 Git 以使用支持 SSL 的 schannel,如

git config --global http.sslBackend schannel

这显然不适用于 macOS 用户。有没有办法在 macOS 上对 Git 客户端执行类似的操作?

我发现我可以在我的 Git 配置中指向证书和私钥,如果 a) 它们在单独的文件中,并且 b) 是 .pem 格式,如下所示:

git config --global http.sslCert /Users/.../cert.pem
git config --global http.sslKey /Users/.../key.pem
git config --global http.sslCertPasswordProtected true

这样做之后,每当我尝试 push/pull 时,Git 客户端会询问私钥的密码,如下所示:

$ git pull
Password for 'cert:////Users/.../cert.pem': *********
Already up to date.

有没有办法告诉 Git 客户端(或底层 curl 客户端)使用 macOS Keychain 来检索证书、密钥以及密钥的密码?

我知道 curl 的较新版本支持 -E/--cert 参数来使用钥匙串,但我不确定是否可以通过 Git 客户端使用。

我使用 Homebrew:

提供的 Git 和 cURL 版本设法找到了在 macOS 上执行此操作的方法
  • 如果您还没有这样做,请安装 Homebrew for macOS
  • 使用 Homebrew 安装 cURL 和 Git:

    brew install curl
    brew install --with-curl git
    

    --with-curl 选项很重要,因为它将强制 Git 使用 cURL 的 Homebrew 版本,其中包括对 macOS Keychain 的必需支持 - 通过 cURL的-E/--cert参数。

    Homebrew 版本的 cURL 支持在用户的钥匙串中查找证书,使用 -E/--cert 参数提供的 name/alias,而 stock macOS 版本的 cURL 没有。

    有必要安装 Git 以支持 homebrew 版本的 cURL,因为如果没有另外说明,它只会使用来自 macOS 的版本。

    如果您已经通过 Homebrew 安装了 Git,则必须使用 --with-curl 选项重新安装它:

    brew reinstall --with-curl git
    

Update With a recent change in the Homebrew Git formula, the --with-curl option was removed. If you still want to use this, you can do the following to install that specific version of Git - this is before the options were removed. To install this specific version of the Git formula, use the following approach (based on these instructions) - 您可能必须先删除现有的 Git 安装,但是:

# Install curl
brew install curl

# Install the last version of the Git formula that still has the --with-curl option
brew install --with-curl https://raw.githubusercontent.com/Homebrew/homebrew-core/a86ae8fc2b24001b3c6460a46dbfc6e323d2a4d1/Formula/git.rb

# Pin Git in Homebrew so that it does not get updated automatically
brew pin git
  • 将证书导入用户的登录钥匙串(双击证书文件,例如,如果它是 .pfx 格式)。检查您用户的 login 钥匙串中是否存在证书(和私钥 - 它们可能位于不同的条目中)并记下证书的名称。我们假设它叫做 git.example.com.

  • 配置 Git 以引用钥匙串中的证书条目。不要将其指向本地文件,而是提供存储在钥匙串中的证书名称。 cURL 的 Homebrew 版本支持这个:

    git config --global http.sslCert git.example.com
    

    如果只想将证书用于特定服务器,可以使用以下语法将设置限制为特定 URL:

    git config --global http."https://git.example.com".sslCert git.example.com
    

完成上述步骤后,每当您 运行 使用 git.example.com 服务器发出 Git 命令时,Git/cURL 应该尝试从您的钥匙串中获取证书.

对于第一次访问,它可能会显示 window 要求您解锁登录钥匙串。提供该钥匙串的密码,并确保单击 Always Allow 按钮。之后,进一步的 Git 命令不应该要求您再次提供密码或钥匙串密码。

您也可以直接编辑 .gitconfig 文件,例如通过添加以下内容以使用特定 URL 的证书:

[http "https://git.example.com"]                                                                                                                                   
    sslCert = git.example.com

您还可以尝试将 p12 文件分成 keycert 组件,使用:

openssl pkcs12 -in /Users/bob/Documents/Certificate-2311d3.p12 -out /Users/bob/Documents/2311d3.key.pem -nocerts -nodes
openssl pkcs12 -in /Users/bob/Documents/Certificate-2311d3.p12 -out /Users/bob/Documents/2311d3.crt.pem -clcerts -nokeys  

如果您 运行 这些命令,系统将提示您输入密码(两次 - 每个命令一次)。现在 keycert 不再受密码保护。

注意:生成的密钥和证书文件不应离开您的本地(希望是加密的)文件系统。它们现在有点像 'unprotected',任何获得它们访问权限的人都可以访问您的远程服务器 - 与常规 ssh 密钥相同。 p12 文件格式被设计为一个便携式容器,只要它受密码保护,您就可以在互联网上发送它,但是一旦您将它放在需要的地方,将它提取到不受保护的组件中,在我看来,完全没问题.

然后您可以使用与您已经尝试过的命令类似的命令克隆您的远程存储库,如下所示:

git init
git remote add origin https://my.webserver.com/something/repo.git
git config http.sslCert /Users/bob/Documents/2311d3.crt.pem
git config http.sslKey /Users/bob/Documents/2311d3.key.pem
git fetch

每次与远程存储库交互时都不会要求您输入密码,git 也不必与 osx 钥匙串交互。

还有许多其他 http 设置可能适用于您的具体情况,我真的建议通读 official git config http documentation,它真的帮助了我(您的 post 也是如此!)。