Git错误 - gpg无法签署数据

时间:2016-12-09 03:17:36

标签: git gnupg

我刚开始使用git,我通过自制软件安装git和gpg。 出于某种原因,我在git commit时遇到此错误 我看了很多关于这个主题的其他stackoverflow问题,但没有一个对我有用。 如何修复此错误以便我可以成功上传。

error: gpg failed to sign the data
fatal: failed to write commit object

30 个答案:

答案 0 :(得分:125)

要进行故障排除,首先要尝试两件事:

  • 运行git config --global gpg.program gpg2,以确保git使用gpg2而非gpg
  • 运行echo "test" | gpg2 --clearsign,以确保gpg2本身正常运作

如果一切顺利,接下来要尝试:

  • 运行brew install pinentry以确保您为密码短语输入安装了一个好的工具

如果在安装完成后重新尝试git commit并仍然获得" failed to sign the data"错误:

  • 运行gpgconf --kill gpg-agent以杀死任何可能挂起的正在运行的代理

如果说没有安装gpgconf或没有--kill选项,那么可能尝试这样做:

  1. cp ~/.gnupg ~/.gnupg-GOOD保存~/.gnupg的副本,以便在需要时恢复到以后
  2. brew install gnupg21安装GnuPG 2.1
  3. 保存~/.gnupg目录副本的原因是GnuPG 2.1可能以与GnuPG 2.0及更早版本不向后兼容的方式创建/更改某些关键数据,因此 if mv ~/.gnupg ~/.gnupg21 && mv ~/.gnupg-GOOD ~/.gnupg。

    否则,有一些基本步骤可以检查您是否有一个可用的GnuPG环境:

    • 运行gpg2 -K --keyid-format SHORT,检查您是否至少有一个密钥对

    如果输出显示您没有GnuPG使用的密钥,那么您需要创建一个:

    • 运行gpg2 --gen-key,让GnuPG引导您完成创建密钥对的步骤

    如果您收到错误消息“Inappropriate ioctl for device”,请执行以下操作:

    • 运行export GPG_TTY=$(tty)和/或将其添加到~/.bashrc˜/.bash_profile

答案 1 :(得分:48)

Git需要知道它与哪个密钥签约。

设置GPG,gpg-agent和gpg.conf文件(请参阅this guide)后,您需要运行

git config --global user.signingkey EB11C755

显然,最后用自己的公钥替换公钥。如果您希望默认情况下对每个提交进行签名,请使用

git config --global commit.gpgsign true

答案 2 :(得分:27)

不知何故,你的git配置为GPG签名每次提交。使用git提交或推送不需要使用GPG进行签名。它可能会出错,因为您的gpg签名机制尚未配置。

如果您是git的新用户,请先尝试不使用GPG签名,然后在以后添加签名,如果您真的需要它。

您可以通过执行以下操作来验证git的配置方式:

git config -l | grep gpg

可能产生零线或多线,包括:

commit.gpgsign=true

如果“commit.gpgsign”为true,则表示您已启用gpg签名。禁用它:

git config --global --unset commit.gpgsign

然后尝试再次运行您的提交。现在应该在没有gpg签名的情况下运行。在你获得基本的git工作之后,你应该尝试将gpg签名添加回混音。

答案 3 :(得分:19)

请参阅@sideshowbarker和@Xavier Ho解决方案,我通过以下步骤解决了我的问题。

假设brew安装了gpg2,

git config --global gpg.program gpg2
brew install pinentry
gpgconf --kill gpg-agent
gpg2 -K --keyid-format SHORT
// no key found then generate new one
gpg2 --gen-key

gpg2 -K --keyid-format SHORT 
  

... /。gnupg的/ pubring.gpg

     

sec rsa2048 / 0A61C6FC 2017-06-29 [SC] [过期日期:2019-06-29]

git config --global user.signingkey 0A61C6FC

我的同事提醒,需要追加

export GPG_TTY=$(tty)

到〜/ .zshrc如果使用zsh,否则附加到〜/ .bash_profile

对于macOS,

gpg2与brew中的gpg组合,因此gpg命令指向gpg2

brew install gpg2
  

brew info gpg

     

gnupg:稳定2.2.6(瓶装)

git config --global gpg.program gpg
gpg -K --keyid-format SHORT 

并且有passnrase-mac用于密码输入

brew install pinentry-mac
vim ~/.gnupg/gpg-agent.conf

添加行

  

pinentry-program / usr / local / bin / pinentry-mac

答案 4 :(得分:5)

解决方案:

Issue: Disabled loopback pinentry mode

要解决此问题,您需要在〜/ .gnupg / gpg.conf 中启用回送针入模式:

cat <<'EOF' >> ~/.gnupg/gpg.conf

use-agent 
pinentry-mode loopback

EOF

以及〜/ .gnupg / gpg-agent.conf 中(如果尚不存在,则创建文件):

cat <<'EOF' >> ~/.gnupg/gpg-agent.conf

allow-loopback-pinentry

EOF

然后使用echo RELOADAGENT | gpg-connect-agent重新启动代理,您应该一切顺利!

Source

答案 5 :(得分:3)

如果它曾经可以工作并且只是说失败,请杀死代理并重试:

gpgconf --kill gpg-agent

检查代理是否再次启动:

echo "test" | gpg --clearsign

答案 6 :(得分:3)

升级到gnupg 2.x后我遇到了这个问题。它会看到gpg2以不同的方式引用键:我的signingkey = ABC98F11中仍然有~/.gitconfig(gpg v1设置)。 gpg2的密钥标识符更长。用gpg --list-secret-keys

查找它们

答案 7 :(得分:3)

可能是您的Git配置设置为 gpgsign = true 。如果您不想要提交您的提交,请尝试将其设置为false。转到存储库文件夹并更改文件

  

nano .git / config

从此......

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@bitbucket.org:yourrepo/project.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[user]
    signingkey = <GPG-KEY>
[commit]
    gpgsign = true

对此...

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@bitbucket.org:yourrepo/project.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[user]
    signingkey = <GPG-KEY>
[commit]
    gpgsign = false

答案 8 :(得分:3)

检查您的密钥是否已过期。修复到期日期后(除非您愿意,无需创建新密钥),git将正常工作。

修复已过期密钥的一种方法:

(注意:$表示命令行提示符,在提示符后键入命令;在每个命令后按Enter键

$ gpg2 --list-keys找到相应的密钥ID(\pub后面的字符)

$ gpg2 --edit-key <key id> - 这会打开gpg shell,提示符更改为gpg>

gpg> expire - 按照说明设置主键的新到期日期

接下来,如果有过期的子项(行sub显示),请重置其过期日期:

gpg> key 1 - 选择第一个子键 gpg> expire - 按照说明为子项

设置新的到期日期

根据需要对每个后续子项重复。

答案 9 :(得分:2)

如果您之前已经设置了pinentry和gpg,但它突然消失了:

检查您的gpg是否有效:

gpg: signing failed: No pinentry

如果显示gpgconf --kill gpg-agent , 只需重新启动gpg守护程序客户端,该客户端就会不时卡住:

echo "test" | gpg --clearsign

现在它应该可以工作了:

number

答案 10 :(得分:1)

当您的GPG密钥已过期时,也会发生此错误。生成一个新密钥并将其添加到Git应解决此问题。

答案 11 :(得分:1)

对我来说,当我从git tag -s切换到pinentry-gnome3(使用pinentry-curses)以便更轻松地进行远程访问时,Debian GNU / Linux上的update-alternatives --config pinentry开始出现此错误。它只发生在git tag -s,而不是gpg(例如gpg --clearsign)本身。

在这种情况下,让它再次运行所需的唯一更改是将export GPG_TTY=$(tty)添加到我的shell启动文件中。

我在这个问题的另一个答案中没有提到“不恰当的ioctl for device”错误消息作为此修复的指示。

注意:由于获得此错误的原因与之前建议export GPG_TTY=$(tty)的人(通常作为旁边提示)在此问题的其他答案中完全不同,我认为这个问题需要另一个答案提到在某些情况下export GPG_TTY=$(tty)可能是主要修复和唯一必要的事情。

答案 12 :(得分:1)

我正在使用它。它具有对zsha的支持,并且可以在Linux的Windows子系统上运行:

export GPG_TTY=$(tty)

答案 13 :(得分:1)

这在ubuntu 18.04上对我有用

检查您的gpg密钥

gpg -K --keyid-format LONG

如果您收到空白回复,请生成一个GPG密钥

gpg --generate-key

重新运行第一个命令,您应该获得如下输出:

sec   rsa3072/95A854E0593B3214 2019-05-06 [SC] [expires: 2021-05-05]
      AF2F7514568DC26B0EB97B9595A854E0593B74D8
uid                 [ultimate] yourname<your_email>
ssb   rsa3072/EFD326E6C611117C 2019-05-06 [E] [expires: 2021-05-05]

设置git唱歌键

git config --global user.singingkey 95A854E0593B3214

那您就好了! (--global是可选的)

或者,如果您不介意使用ssh键签名

git config commit.gpgsign false

请注意,根据此问题herehere ,由于安全问题,不建议这样做

答案 14 :(得分:1)

我必须将gpg.program修复为gpg的绝对路径:

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

我将Windows与cygwin一起使用。

答案 15 :(得分:1)

我在macOS上遇到此错误-尝试进行故障排除并尝试使用gpg2 --list-keys列出密钥,以查看它们是否已过期-我验证了密钥是否未过期,并且使用在我的配置中设置了正确的密钥git config --global user.signingkey

运行这些命令后,我突然能够再次进行签名提交而没有问题。我没有更改配置文件或密钥-甚至没有创建新的Terminal实例。好像gpg2在我的Mac上处于某种奇怪的状态。

答案 16 :(得分:0)

什么是 gpg:GNU 隐私保护

用法

<块引用>

GPG 是确保两方安全通信的绝佳方法。它允许在不安全的网络中轻松共享敏感信息。

简单的解决方案:

Step1:请检查密钥是否过期

<块引用>

gpg -K --keyid-format 简短内容

Step2:如果它没有过期

<块引用>

git config --global user.signingkey

答案 17 :(得分:0)

使用 GIT_TRACE=1 查看 Git 失败的地方,然后检查 Git 使用的所有自定义配置以及定义它们的位置,然后根据您的需要覆盖:

GIT_TRACE=1 git commit -S -m "this will tell you wich intern git command failed"

git config --list --show-scope --show-origin

对我来说,我有 error: gpg failed to sign the datafatal: failed to write commit object,因为 Git 出于某种原因默认使用 smimesign ,即使我取消设置 gpg.x509.program 键和 smimesign couldn't find my key

所以我必须明确告诉 Git 使用 gpg 来代替:

git config --local gpg.x509.program gpg

答案 18 :(得分:0)

我在 linux/windows 平台上都遇到了这个问题,就我而言,我只需要更加注意输出。这令人难以置信,因为我可以使用相同的设置在其他存储库中签署提交。

git commit -m "test signing"
gpg: skipped "***63231079***": No secret key
gpg: signing failed: No secret key
error: gpg failed to sign the data
fatal: failed to write commit object

我强调了“跳过”这一行。请注意,有时当您克隆一个 repo 时,他们会分配一个密钥:这个问题让我很困惑,以至于我对我可以访问的分叉 repo 进行了核攻击,并在 github 上重新分叉。然后因为我在考虑“全局配置”,我从没想过要查看本地存储库配置,当我这样做时,我注意到了这一点:

[user]
    signingkey = 63231079

嗯,当然它不会工作 nimrod,git 默认首先使用本地设置,所以这就是为什么您的密钥从未被拿起的原因。我通过 git config 设置了指针,此后一直有效。

答案 19 :(得分:0)

对于我的带有 GUI 和 gpg 2.2.19 的 Linux 系统,无论是杀死 gpg-agent(它再次启动自己)、取消设置 $DISPLAY 还是设置 $GPG_TTY 都对我有用,因为它试图使用pinentry-gnome 从控制台询问密码。而且我的密钥没有过期。

来自超级用户对类似问题的回答,How to force GPG to use console-mode pinentry to prompt for passwords?,如果您的系统具有 GNOME 等 GUI,并且您的包管理器配置为使用 GUI pinentry 程序,则该问题也可能发生,这就是原因为什么它挂了。

我不得不切换到 pinentry-tty 才能让 GPG 再次对消息进行签名。在 Ubuntu 上,这可以使用我将在此处引用的链接中的步骤完成:

sudo apt install pinentry-tty
sudo update-alternatives --config pinentry

第二个命令会显示一个 pinentry 程序列表,并要求你输入一个数字来选择一个,所以输入与 pinentry-tty 对应的那个,然后不需要任何额外的努力,签名消息(和 git commits)应该重新工作。

答案 20 :(得分:0)

我刚刚在VSCode更新时遇到了这个问题。我认为GPG代理已挂起,因为该命令花了好几秒钟才能运行,然后才出错。运行gpgconf --kill gpg-agent会将其重置并为我修复。

答案 21 :(得分:0)

就我而言,我必须将GitHub设置中存储的名称与密钥的名称和注释匹配。

因此,如果def generate_big_random_letters(filename,size): import random import string chars = ''.join([random.choice(string.letters) for i in range(size)]) #1 with open(filename, 'w') as f: f.write(chars) pass if __name__ == '__main__': generate_big_random_letters("temp_big_letters.txt",1024*1024) 返回gpg --list-keys,则您在.gitconfig中的名称应为uid [ultimate] Joe Blogs (fancy comment) <email@example.com>

最初,我将我的名字设置为Joe Blogs (fancy comment),GPG找不到我的密钥,并在Joe Blogs中显示“ no secret key”错误。不幸的是,没有strace不会出现该错误,并且会得到通用的

strace

答案 22 :(得分:0)

就我而言,在无法适应密码提示的小型 <?php //URL path. eg: index-en/job.php $path = trim($_SERVER['REQUEST_URI'],'/'); //language from URL. eg: index-en $lang = explode('/',$path)[0]; //Paths in other languages: eg: 'tr' => 'index-cn/job.php' $langs = [ 'en'=>preg_replace("/$lang/",'../en',$path,1), 'tr'=>preg_replace("/$lang/",'../tr',$path,1), ]; ?> <ul class="dropdown-menu"> <li> <a href="<?= $langs['tr']?>">Türkçe</a> </li> <li> <a href="<?= $langs['en']?>">English</a> </li> </ul> 窗口上运行git commit时,发生了此错误。

tmux

答案 23 :(得分:0)

就我而言,我在此处的提交签名文档中给出了混合的gpg配置和smimesign配置:https://help.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key

工作了几个小时后,我发现纠正它的最佳方法是取消与gpg相关的所有操作,然后重新配置gpg。

如@Jason Thrasher的答案中所述,使用以下命令查找与gpg相关的所有git配置:

git config -l | grep gpg

然后使用以下方法在本地以及本地取消所有设置:

git config --global --unset <config_name>
git config --local --unset <config_name>

然后按照上面给出的官方文档进行重新配置。 希望这会有所帮助。

答案 24 :(得分:0)

对我来说,简单的brew unintstall gnupg && brew cask reinstall gpg-suite就可以解决问题。

它会卸载(以我为例)手动执行自制程序的gpg,然后重新安装整个GPG套件。

答案 25 :(得分:0)

如果您正在使用智能卡/ yubikey 存储GPG密钥,并且通过存储在卡中的密钥设置了git config的signkey(并且上述所有答案似乎都没有以解决您的问题),您卡的PIN码被阻止可能是导致此问题的根本原因。

要检查被阻止的PIN:

gpg --card-status

如果计数器类似于

Reader ...........: Yubico YubiKey
PIN retry counter : 3 0 3

然后您的PIN码将被阻止(尝试3次失败)。

要取消屏蔽PIN码,

gpg --card-edit
gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. … detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 2
PIN unblocked and new PIN set.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

答案 26 :(得分:0)

当git config中的密钥过期时,也可能导致相同的错误。

请检查cat .git/config的内容,并查找signingkey值,并检查其是否过期。如果是,请用新的更新。

答案 27 :(得分:0)

我解决了安装brew install gpg2然后执行git config --global gpg.program gpg2

的问题

答案 28 :(得分:0)

我已为git / certify / sign&amp;密钥显示在将来过期(工作好几天后):

encrypt

创建一个新密钥而不添加单独的子密钥来解决问题。

答案 29 :(得分:-3)

这将帮助您摆脱它

git config commit.gpgsign false