gpg无法签署致命的数据:无法写入提交对象[Git 2.10.0]

时间:2016-09-14 15:42:05

标签: git github gpg-signature

我在pretty发行说明的Git 2.10属性上发表了一些文章。继续将git升级到2.10.0并对全局.gitconfig进行更改,结果如下 -

[filter "lfs"]
    clean = git-lfs clean %f
    smudge = git-lfs smudge %f
    required = true
[user]
    name = xyz
    email = abc.def@gmail.com
    signingkey = AAAAAAA
[core]
    excludesfile = /Users/xyz/.gitignore_global
    editor = 'subl' --wait
[difftool "sourcetree"]
    cmd = opendiff \"$LOCAL\" \"$REMOTE\"
    path = 
[mergetool "sourcetree"]
    cmd = /Applications/SourceTree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\"
    trustExitCode = true
[alias]
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
[color "diff"]
    old = red strike
    new = green italic

但是现在我尝试使用

签署我的提交
git commit -a -S -m "message"

我看到以下错误 -

  

您需要使用密码来解锁

的密钥      

用户:“XYZ(数字签名)”

     

2048位RSA密钥,ID AAAAAAAA,创建于2016-07-01

     

错误:gpg无法签署数据致命错误:无法写入提交   对象

注意 - 我仍然可以使用git commit -a -m "message"提交更改

有没有办法克服同样的问题?或gpg配置所需的任何更改以便与git的升级相配?

更新1

Is there a way to "autosign" commits in Git with a GPG key?之后寻求进一步的实用性。我已经使用

配置了密钥
git config --global user.signingkey ED5CDE14(with my key) 
git config --global commit.gpgsign true

并且很明显地得到了相同的错误。

41 个答案:

答案 0 :(得分:299)

我在OSX遇到了这个问题。

原始答案:

似乎gpg更新(brew)已更改为gpggpg1的位置,您可以更改git查找gpg的二进制文件:

git config --global gpg.program gpg1

如果你没有gpg1:brew install gpg1

更新的答案:

看起来gpg1已被弃用/ "gently nudged out of usage",所以你可能应该实际更新为gpg2,不幸的是,这需要更多的步骤/一点时间:

brew upgrade gnupg  # This has a make step which takes a while
brew link --overwrite gnupg
brew install pinentry-mac
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
killall gpg-agent

第一部分安装gpg2,后者安装a hack required to use it。对于故障排除,请参阅this answer(虽然这是关于linux而不是brew),但它提示了一个很好的测试:

echo "test" | gpg --clearsign  # on linux it's gpg2 but brew stays as gpg

如果此测试成功(没有错误/输出包括PGP签名),您已成功更新到最新的gpg版本。

您现在应该可以再次使用git签名!
值得注意的是你需要:

git config --global gpg.program gpg  # perhaps you had this already? On linux maybe gpg2
git config --global commit.gpgsign true  # if you want to sign every commit

注意:运行已签名的提交后,您可以使用以下命令验证其签名:

git log --show-signature -1

将包含上次提交的gpg信息。

答案 1 :(得分:211)

如果使用gnupg2和gpg-agent 2.x,请务必设置环境变量GPG_TTY

export GPG_TTY=$(tty)

请参阅GPG’s documentation about common problems

答案 2 :(得分:114)

如果一切都失败了,请使用GIT_TRACE=1尝试查看git实际在做什么:

$ GIT_TRACE=1 git commit -m "Add page that always requires a logged-in user"
20:52:58.902766 git.c:328               trace: built-in: git 'commit' '-vvv' '-m' 'Add page that always requires a logged-in user'
20:52:58.918467 run-command.c:626       trace: run_command: 'gpg' '--status-fd=2' '-bsau' '23810377252EF4C2'
error: gpg failed to sign the data
fatal: failed to write commit object

现在手动运行失败的命令:

$ gpg -bsau 23810377252EF4C2
gpg: skipped "23810377252EF4C2": Unusable secret key
gpg: signing failed: Unusable secret key

事实证明,我的钥匙已过期,git不应该受到责备。

答案 3 :(得分:40)

我通过简短简单食谱完成

MacOS上的自动签名提交(全球和不同的IDE):

this way中获取signingkey

brew install gnupg gnupg2 pinentry-mac
git config --global user.signingkey <YOUR_SIGNING_KEY>
git config --global commit.gpgsign true
git config --global gpg.program gpg

将以下内容放入gpg.conf文件(使用nano ~/.gnupg/gpg.conf命令编辑文件):

no-tty

将以下内容放入gpg-agent.conf文件(使用nano ~/.gnupg/gpg-agent.conf命令编辑文件):

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

答案 4 :(得分:31)

可能有助于杀死可能会遇到旧数据的进程gpg-agent。所以新的gpg-agent启动会要求输入密码

答案 5 :(得分:9)

我的两分钱在这里

在创建密钥并将其添加到gpg-agent时,您将定义一个名为passphrase的名称。现在passphrase到期了,gpg需要您再次输入它来解锁密钥,以便您可以重新开始签名。

当您使用任何其他与gpg连接的程序时,gpg会提示您输入密码,不会出现 not (基本上是gpg-agent守护进程可能无法在stdin中向您显示输入对话框。

一种解决方案是gpg --sign a_file.txt,然后输入创建密钥时输入的密码,然后一切都应该正常(gpg-agent应该会自动签名)

有关如何为密码设置更长的超时时间,请参见this answer,这样您就不必一直这样做。

或者您可以使用ssh-keygen -p

完全删除密码短语

答案 6 :(得分:8)

2016年10月更新:issue 871确实提及&#34;签署停止在Git 2.9.3和#34中工作;

两天前(2016年10月4日)发布的

Git for Windows 2.10.1修复了提交和标记的交互式GPG签名。

  

git中最近的gpg-sign更改(在Linux上没有引入任何问题)暴露了一个问题,在Windows上,非MSYS2-git与MSYS2-gpg交互。

原始答案:

阅读&#34; 7.4 Git Tools - Signing Your Work&#34;,我认为你有#34; user.signingkey&#34;配置集。

围绕gpg的最后一次大型重构(在Git 2.10之前)位于commit 2f47eae2a,此处错误消息已移至gpg-interface.c

登录该文件会显示最近commit af2b21e(Git 2.10)

的变化
  

gpg2默认使用长格式,但大多数发行版似乎仍然有#34; gpg&#34;由于兼容性原因,是较旧的1.x版本。旧版本的gpg只显示32位短ID,这是非常不安全的。

     

这对验证本身并不重要:如果是   验证通过,pgp签名是好的   但如果你不这样做   实际上还有密钥,想要获取它,或者你想检查   确切地说,哪个密钥用于验证并想要检查它,我们   应该更精确地指定密钥。

请检查您如何指定user.signingkey配置以及您正在使用的gpg版本(gpg1或gpg2),以查看它们是否对错误消息有任何影响。

还有commit 0581b54更改gpg failed to sign the data错误消息的条件(与commit 0d2b664的补充):

  

我们目前都没有从stderr那里读过。但是,我们希望在未来的补丁中,所以这也为我们做好了准备(在这种情况下gpg 在读取所有输入之前写),但同样,关键uid不太可能填满管道缓冲区。)

Commit 4322353显示gpg现在使用临时文件,因此可能存在正确的问题。

  

让我们转换为使用tempfile对象,它处理   对我们来说很难,并添加缺少的清理电话。

答案 7 :(得分:7)

git跟踪非常适合我的情况...

   GIT_TRACE=1 git commit -m "a commit message"
   13:45:39.940081 git.c:344               trace: built-in: git commit -m 'a commit message'
   13:45:39.977999 run-command.c:640       trace: run_command: gpg --status-fd=2 -bsau 'full name <your-email@domain.com>'
   error: gpg failed to sign the data
   fatal: failed to write commit object

我需要按照git所检查的格式生成一个初始密钥。最好照原样复制上面传递给-bsau的值并在下面使用。

就这样,

   gpg --quick-generate-key "full name <your-email@domain.com>"

然后它起作用了。

希望有帮助。

答案 8 :(得分:7)

使用cygwin,我最近切换到gpg2。然后,在设置git config gpg.program gpg2后,我在使用git进行签名时遇到了同样的问题。

尝试echo "test" | gpg2 --clearsign查看gpg2是否正常工作。我发现这是设置git config gpg.program gpg的最简单的解决方案,因为它可行。但是你也会以这种方式得到更好的错误 - 例如你需要安装pinentry。

答案 9 :(得分:6)

对于在 MacOS 计算机上遇到此问题的任何人,请尝试以下操作:

  1. class test { static propTypes = { optionalBool: PropTypes.bool, requiredProperty: PropTypes.number.isRequired }}
  2. brew uninstall gpg
  3. brew install gpg2(如果需要)
  4. brew install pinentry-mac通过使用算法创建密钥。
  5. 通过执行以下命令获取生成的密钥:gpg --full-generate-key
  6. 在这里gpg --list-keys设置密钥
  7. git config --global user.signingkey <Key from your list>
  8. git config --global gpg.program /usr/local/bin/gpg
  9. 如果要将密钥导出到GitHub,请:git config --global commit.gpgsign true 并将此密钥通过GPG密钥添加到GitHub:https://github.com/settings/keys(包括START和END行)

如果问题仍然存在:

gpg --armor --export <key>

test -r ~/.bash_profile && echo 'export GPG_TTY=$(tty)' >> ~/.bash_profile

如果问题仍然存在:

安装https://gpgtools.org并通过从菜单栏中按 Sign 对您使用的密钥进行签名: Key -> Sign

如果问题仍然存在:

转到:您的全局echo 'export GPG_TTY=$(tty)' >> ~/.profile文件,以我为例:⁨.gitconfig 并修改 .gitconfig 文件(请确保“电子邮件”和“名称”与您在生成密钥时创建的名称相同)

/Users/gent/.gitconfig

答案 10 :(得分:5)

我遇到了同样的问题。我很高兴地报告问题不在于git 2.10.0,而在于gnupg 1.4.21

暂时将gnupg降级到1.4.20为我解决了这个问题。

如果您正在使用自制软件并且像我一样升级了软件包,那么您可以运行brew switch gnupg 1.4.20来还原。

答案 11 :(得分:4)

我在Ubuntu 18.04上遇到此错误,结果证明我的密钥已过期

要查看此内容,我运行了此文件,并确认我的密钥已过期:

gpg --list-keys

要解决此问题,我运行了(使用上一条命令中显示的ID):

gpg --edit-key <ID>

从那里,我扩展了these instructions之后的key 0key 1的有效期,最后将其归结为先输入key 0然后输入expire并遵循提示。然后重复key 1

然后,要进行测试,我跑了:

echo test | gpg --clearsign

在修复之前,它因错误而失败:

  

gpg:无默认密钥:无密钥
  gpg:[stdin]:清除符号失败:无密钥

但是在修复之后,相同的命令成功地对消息进行了签名,所以我知道事情再次起作用了!

答案 12 :(得分:4)

按照以下网址设置已签名的提交 https://help.github.com/en/articles/telling-git-about-your-signing-key

如果仍然得到 gpg无法签署致命数据: 未能写入提交对象

这不是git的问题,这是GPG的问题 请按照以下步骤操作

1。gpg --version

  1. echo "test" | gpg --clearsign

如果显示:

gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
  1. 然后使用export GPG_TTY=$(tty)

4。然后再次尝试echo "test" | gpg --clearsign 其中具有PGP签名。

  1. git config -l | grep gpg

gpg.program = gpg commit.gpgsign = true

6.apply git commit -S -m "commitMsz"

答案 13 :(得分:3)

在OS X上,通过brew使用gnupg2只是杀死gpg代理,有时会发生:

pkill -9 gpg-agent

并根据需要设置env变量:

export GPG_TTY=$(tty)

另请参见Common GPG problemsthis answer here too.

答案 14 :(得分:3)

如果您像我一样将 WSL 与您的 IDE 一起使用,您可能会遇到这个问题,因为在使用 IDE 的提交界面提交时,密码短语“window”永远不会出现(WSL 不支持GUI 应用程序尚未)

修复方法是简单地使用命令行 git,因为它有自己的 cli 窗口供您输入密码。您还需要确保终端“大”到足以让它弹出(我知道很惊讶)

https://regex101.com/r/TGVwso/1

答案 15 :(得分:3)

我一定不小心更新了gpg,因为在尝试测试gpg是否有效后我得到了这个信息:

gpg: WARNING: server 'gpg-agent' is older than us (2.1.21 < 2.2.10)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.

运行gpgconf --kill all为我修复了该问题。

希望这对某人有帮助。

答案 16 :(得分:3)

可能是悬挂的gpg代理。

尝试gpgconf --kill gpg-agent as discussed here

答案 17 :(得分:3)

如果与您的GPG密钥相关联的电子邮件与您在git中使用的电子邮件不同,则需要在密钥中添加其他用户ID,或者使用与电子邮件完全匹配的密钥。

您可以使用以下方法添加其他UID:

  

$ gpg --edit-key

参见mo https://superuser.com/questions/293184/one-gnupg-pgp-key-pair-two-emails

答案 18 :(得分:2)

上面的答案很棒,但它们对我不起作用。解决了我的问题是导出了公共秘密键。

列出我们从

导出的机器的密钥
$ gpg --list-keys
/home/user/.gnupg/pubring.gpg
--------------------------------
pub 1024D/ABCDFE01 2008-04-13
uid firstname lastname (description) <email@example.com>
sub 2048g/DEFABC01 2008-04-13

导出密钥

$ gpg --output mygpgkey_pub.gpg --armor --export ABCDFE01
$ gpg --output mygpgkey_sec.gpg --armor --export-secret-key ABCDFE01

转到我们导入并导入的机器

$ gpg --import ~/mygpgkey_pub.gpg
$ gpg --allow-secret-key-import --import ~/mygpgkey_sec.gpg
bingo bongo,你已经完成了!

参考:https://www.debuntu.org/how-to-importexport-gpg-key-pair/

PS。我的钥匙最初是在bootcamp windows 7上制作的,我把它们导出到我的mac air(同样的物理机器,虚拟不同)

答案 19 :(得分:2)

如果您在没有 Rosetta 的 M1 芯片上使用自制软件,您需要指定 pinentry-program 二进制文件的不同位置,因为它安装在不同的位置。

Andy Hayden 的更新答案应修改如下:

brew upgrade gnupg  # This has a make step which takes a while
arch -arm64 brew link --overwrite gnupg
arch -arm64 brew install pinentry-mac
echo "pinentry-program /opt/homebrew/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
killall gpg-agent

答案 20 :(得分:2)

我遇到了类似的问题,最新的Git源代码(2.12.2)以及所有依赖项的最新来源(Zlib,Bzip,cURL,PCRE,ReadLine,IDN2,iConv,Unistring等)构建。

事实证明libreadline给出了GnuPG问题:

$ gpg --version
gpg: symbol lookup error: /usr/local/lib/libreadline.so.7: undefined symbol: UP

当然,试图通过-vvv从Git获取有用的信息失败,所以失败是个谜。

要解决因ReadLine导致的PGP失败,请按照Can't update or use package manager -- gpg error

中的说明进行操作
  

在终端:

ls /usr/local/lib
     

那里有一堆readline libs(libreadline.so.BLAH-BLAH)   所以我:

su
mkdir temp
mv /usr/local/lib/libreadline* temp
ldconfig

答案 21 :(得分:2)

确保正确设置了您的电子邮件。

sudo apt-get install xtitle

答案 22 :(得分:1)

对我来说,brew更新了gnupggpg,所以我要做的就是解决这个问题。

brew link --overwrite gnupg

gpg链接到正确的位置,我可以通过which gpg进行确认,之后一切正常。

答案 23 :(得分:1)

就我而言,所有解​​决方案都不起作用,因为我没有手动进入 ~/.gitconfig 并删除以下内容,因为我创建了一个不再是旧 X.509 密钥的新密钥,因此我删除了跟随然后我的新密钥开始工作。

[gpg]
    program = gpg
    format = x509
[gpg "x509"]
    program = smimesign

答案 24 :(得分:1)

以上都不适合我,我通常使用我的 IDE 终端。

我时不时地遇到这个错误,在大多数情况下它工作得很好。 运行后发现问题

 echo "test" | gpg --clearsign

gpg: signing failed: Screen or window too small
gpg: [stdin]: clear-sign failed: Screen or window too small

解决办法:增加终端窗口大小。

答案 25 :(得分:1)

我在Ubuntu 18.04上遇到相同的错误,也担心了数周。 终于意识到gpg2没有指向任何东西。 所以只需运行

git config --global gpg.program gpg

塔达,就像魅力一样。

Signed commit

您的提交现在将带有已验证的标记。

答案 26 :(得分:1)

上述答案似乎都不符合我的问题。我的gpg二进制文件(/usr/local/bin/gpg -> /usr/local/MacGPG2/bin/gpg2)是作为GPG Suite的一部分安装的,而不是brew。

然而,我觉得这个建议归结为:“使用任何gpg二进制文件是最新的brew版本”。所以我试过了:

brew update
brew upgrade git
brew install gpg

# the following are suggestions from brew's Caveats, to make `/usr/local/bin/gpg`
# point to the brew binary:
rm '/usr/local/bin/gpg'
brew link --overwrite gnupg2

我确认我已正确更改gpg $PATH以指向brew中的新可执行文件:

 which gpg
/usr/local/bin/gpg
 ls -l /usr/local/bin/gpg
lrwxr-xr-x  1 burger  admin  33 Feb 13 13:22 /usr/local/bin/gpg -> ../Cellar/gnupg2/2.0.30_3/bin/gpg

我还明确告诉git使用gpg二进制文件:

git config --global gpg.program gpg

嗯,也许这不是完全不透水的,因为它对路径很敏感。实际上,我并没有毫无疑问地确认git已经切换到调用brew gpg

无论如何:这一点都不足以让git commit再次成功签署我的提交。

对我有用的事情最终是更新GPG套件。我正在运行2016.7版本,我发现更新到2016.10为我解决了这个问题。

我打开GPG Keychain.app,点击“检查更新...”。使用新版本:signed commits再次正常工作。

答案 27 :(得分:1)

非常类似于@birchlabs,经过大量的搜索/搜索,我发现它不是GPG,而是GPG Suite。我做了cask reinstall gpg-suite,它为我解决了。

答案 28 :(得分:1)

简单地设置它:

brew uninstall gpg 

brew install gpg2

答案 29 :(得分:1)

我每次注销时都会遇到这个错误,然后在我的 MacOS 上再次登录。解决方案只是一个简单的命令:

killall gpg-agent

我认为这只是 gpg 代理的错误,杀死它然后重新工作。

答案 30 :(得分:1)

如果您的问题是 Visual Studio Code 不允许提交,但您已经设置了 GPG 签名,那么带有 import numpy as np a = np.array([[0.1, 0.5], [0.7, 0.4], [0.6, 0.9]]) b = a[a[:, 0] < 0.5] print(b) 的一行答案是:

bash

如果您在 git config --global gpg.program `which gpg2` 中有 gpg 但没有 PATH,则直接使用它。

答案 31 :(得分:0)

如果您不想处理brew来安装gpg,似乎有时会遇到问题,只需从GPG Tools下载gpg工具。

在浏览向导时,单击“定制安装”,然后取消选择邮件插件(除非您要使用它)。这些工具似乎可以正常工作,不会遇到任何问题,而且它可以在您首次签署提交后记住您的密码。无需其他配置,只需告诉git about which key使用即可。

至少这是我的经验。

答案 32 :(得分:0)

我偶然发现此错误不是因为任何配置问题,而是因为我的密钥已过期。在OSX上扩展其有效性的最简单方法是打开GPG钥匙串应用程序(如果已安装),它将自动提示您扩展它。两次单击,您就完成了。希望这对其他Google员工有所帮助:)

答案 33 :(得分:0)

prezto的另一个zsh变体中使用它。那里的问题是我的git回购是新的,没有将node_modules添加到.gitignore中。我将node_modules添加到.gitignore后,就再也看不到这个问题了。因此,我的假设是git-info由于这些node_modules大而需要时间。

答案 34 :(得分:0)

对于我来说,这突然开始在Ubuntu上发生,不确定是否最近进行了更新,但是所有现有问题都不适合我(我设置了GPG_TTY,试图杀死代理等。 )。独立的gpg命令因以下错误而失败:

$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

test
gpg: signing failed: Operation cancelled
gpg: [stdin]: clear-sign failed: Operation cancelled

我尝试使用gpg选项运行--debug-all,并注意到以下输出:

gpg: DBG: chan_3 <- INQUIRE PINENTRY_LAUNCHED 27472 gnome3 1.1.0 /dev/pts/6 screen-256color -
gpg: DBG: chan_3 -> END
gpg: DBG: chan_3 <- ERR 83886179 Operation cancelled <Pinentry>
gpg: signing failed: Operation cancelled

以上内容表明pinentry程序存在问题。 Gpg通常为我运行pinentry-curses,所以我更改了pinentry-tty(我必须先熟练安装它)并且错误消失了(尽管我不再获得全屏密码输入,但是我没有无论如何)。要进行此更改,我必须将pinentry-program /usr/bin/pinentry-tty行添加到~/.gnupg/gpg-agent.conf并使用gpgconf --kill gpg-agent杀死该代理(下次它将重新启动)。

答案 35 :(得分:0)

有点奇怪,但是请确保您的终端足够大!您可以通过运行echo test | gpg --clearsign来判断它是否太小-它会给您一个非常明显的错误消息,让您知道。如果不够大,您的GPG代理将无法显示其小的ncurses框。

如果您使用GUI代理或不使用ncurses的工具,则此方法将不适用。

答案 36 :(得分:0)

我已经看到了类似的答案,但没有什么比对我有用的东西更准确的了。在Linux上,我必须使用以下命令杀死并重新启动gpg-agent

$ pkill gpg-agent
$ gpg-agent --daemon
$ git commit ...

这帮了我大忙。看来您确实需要根据其他评论的意思将user.signingkey设置为私钥。

答案 37 :(得分:0)

就我而言,其他答案中提到的解决方案均无效。我发现问题是特定于一个存储库的。删除并克隆存储库再次解决了该问题。

答案 38 :(得分:0)

如果这只是随机发生并且过去一直运作良好,就像我的情况一样,请尝试退出(cmd+shift+q)并重新登录。为我工作

答案 39 :(得分:-1)

我尝试了很多建议,但没有运气,最终得到了这个。我知道这不完美,但我只是想尽快回到我的工作中。

git config commit.gpgsign false

答案 40 :(得分:-2)

使用以下命令检查是否启用了gpg

  Exception in thread "main" java.lang.NullPointerException
at org.apache.beam.sdk.runners.TransformHierarchy$Node.
 visit(TransformHierarchy.java:579)
------
    at com.momagic.df.tableaureportsetl.TestBQPipeline8.main
  (TestPipeline.java:147)

如果返回true,请运行以下命令将其禁用

git config -l | grep gpg

成功运行上述命令后,您应该可以运行git commit命令。