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

问题描述 投票:191回答:26

我在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 = [email protected]
    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

并且很明显得到同样的错误。

git github gpg-signature
26个回答
313
投票

我在OSX遇到了这个问题。

Original answer:

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

git config --global gpg.program gpg1

如果你没有gpg1:brew install gpg1

Updated answer:

看起来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信息。


7
投票

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

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


7
投票

git trace对我的情况很有启发......

   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 <[email protected]>'
   error: gpg failed to sign the data
   fatal: failed to write commit object

我需要根据git检查的格式生成初始密钥。最好将日志中传递给-bsau的值复制到日志中,并在下面使用。

它变成了,

   gpg --quick-generate-key "full name <[email protected]>"

然后它奏效了。

希望有所帮助。


5
投票

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

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

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


3
投票

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

您可以使用以下命令添加另一个UID:

$ gpg --edit-key

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


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为我修复它。

希望这有助于某人。


3
投票

可能是一个挂gpg代理。

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


2
投票

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

git config --global user.email "[email protected]"

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

2
投票

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

列出我们从中导出的机器的密钥

$ gpg --list-keys
/home/user/.gnupg/pubring.gpg
--------------------------------
pub 1024D/ABCDFE01 2008-04-13
uid firstname lastname (description) <[email protected]>
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

宾果邦戈,你做完了!

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

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


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,点击“检查更新......”。使用新版本:签名提交再次正常工作。


227
投票

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

export GPG_TTY=$(tty)

GPG’s documentation about common problems


1
投票

简单地设置它:

brew uninstall gpg 

brew install gpg2

1
投票

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


1
投票

我在Ubuntu 18.04上也遇到了同样的错误,也担心了好几周。终于意识到gpg2并没有指向任何东西。所以简单地运行

git config --global gpg.program gpg

而田田,它就像魅力一样。

Signed commit

您的提交现在将使用它们验证标记。


0
投票

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


0
投票

就我而言,其他答案中提到的解决方案都没有奏效。我发现问题是针对一个存储库的。删除和克隆回购再次解决了这个问题。


-1
投票

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

git config commit.gpgsign false

-2
投票

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

git config -l | grep gpg

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

git config --global --unset commit.gpgsign

成功运行上面的命令后,您应该能够运行git commit命令。


117
投票

如果一切都失败了,请使用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不应该受到指责。


42
投票

我通过这个简单易用的食谱完成了它:

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

signingkey获取你的this way

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

39
投票

可能有助于杀死可能卡住旧数据的gpg-agent进程。所以新的gpg-agent开始会要求密码


10
投票

我的两分钱在这里:

当您为gpg-agent创建并添加密钥时,您可以定义名为passphrase的内容。既然passphrase在某个时候到期,gpg需要你再次输入它来解锁你的钥匙,以便你可以再次开始签名。

当你使用与gpg接口的任何其他程序时,gpg的提示输入你的密码短语不会出现(当守护进程时,gpg-agent基本上不能显示stdin中的输入对话框)。

其中一个解决方案是gpg --sign a_file.txt然后输入你在创建密钥时输入的密码,然后一切都应该没问题(gpg-agent应该自动签名)

请参阅this answer,了解如何为密码短语设置更长的超时时间,这样您就不必一直这样做。

或者你可以用ssh-keygen -p完全删除密码


10
投票

按照以下网址设置签名提交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.然后再次尝试获得PGP签名的echo "test" | gpg --clearsign

  1. git config -l | grep gpg

gpg.program = gpg commit.gpgsign = true

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


9
投票

2016年10月更新:issue 871确实提到“签署停止在Git 2.9.3中工作”

Git for Windows 2.10.1两天前发布(2016年10月4日)已经修复了交互式GPG签名提交和标记。

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


原始答案:

阅读“7.4 Git Tools - Signing Your Work”,我假设你有“user.signingkey”配置集。

围绕gpg的最后一次大型重构(在Git 2.10之前)是在commit 2f47eae2a,这里错误消息被转移到gpg-interface.c

登录该文件显示commit af2b21e最近的变化(Git 2.10)

gpg2默认使用了长格式,但由于兼容性原因,大多数发行版似乎仍然将“gpg”作为旧的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对象,它为我们处理硬案例,并添加缺少的清理调用。


9
投票

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

  1. brew uninstall gpg
  2. brew install gpg2
  3. brew install pinentry-mac(如果需要)
  4. gpg --full-generate-key使用算法创建密钥。
  5. 通过执行:gpg --list-keys获取生成的密钥
  6. 在这里设置密钥git config --global user.signingkey <Key from your list>
  7. git config --global gpg.program /usr/local/bin/gpg
  8. git config --global commit.gpgsign true
  9. 如果你想将你的Key导出到GitHub,那么:gpg --armor --export <key>并将这个键添加到GPG键的GitHub:https://github.com/settings/keys(包含START和END行)

如果问题仍然存在:

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

echo 'export GPG_TTY=$(tty)' >> ~/.profile

如果问题仍然存在:

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

如果问题仍然存在:

转至:您的全局.gitconfig文件,在我的情况下位于:/Users/gent/.gitconfig并修改.gitconfig文件(请确保电子邮件和名称与您在生成密钥时创建的文件相同):

[user]
	email = [email protected]
	name = Gent
	signingkey = <YOURKEY>
[gpg]
	program = /usr/local/bin/gpg
[commit]
	gpsign = true
	gpgsign = true
[filter "lfs"]
	process = git-lfs filter-process
	required = true
	clean = git-lfs clean -- %f
	smudge = git-lfs smudge -- %f
[credential]
	helper = osxkeychain
© www.soinside.com 2019 - 2024. All rights reserved.