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

Nam*_*man 253 git github gpg-signature

我在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
Run Code Online (Sandbox Code Playgroud)

但现在我尝试使用我的提交签名

git commit -a -S -m "message"
Run Code Online (Sandbox Code Playgroud)

我看到以下错误 -

你需要一个密码来解锁密钥

用户:"XYZ(数字签名)"

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

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

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

有没有办法克服同样的问题?或者gpg配置中需要进行任何更改才能与git的升级相提并论?


更新1

还寻求进一步的实用性,以下是否有办法用GG密钥在Git中"自动签名"提交?.我已经使用了配置密钥

git config --global user.signingkey ED5CDE14(with my key) 
git config --global commit.gpgsign true
Run Code Online (Sandbox Code Playgroud)

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

And*_*den 372

我在OSX遇到了这个问题.

原始答案:

这似乎是改变的位置(BREW的)一个GPG更新gpggpg1,你能改变的Git中查找GPG二进制:

git config --global gpg.program gpg1
Run Code Online (Sandbox Code Playgroud)

如果你没有gpg1 : brew install gpg1.

更新的答案:

看起来gpg1被弃用/ "轻轻推出使用",所以你可能实际上应该更新到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
Run Code Online (Sandbox Code Playgroud)

第一部分安装gpg2,后者是使用它所需的黑客.对于故障排除,请参阅此答案(虽然这是关于linux而不是brew),它建议一个很好的测试:

echo "test" | gpg --clearsign  # on linux it's gpg2 but brew stays as gpg
Run Code Online (Sandbox Code Playgroud)

如果此测试成功(没有错误/输出包括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
Run Code Online (Sandbox Code Playgroud)

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

git log --show-signature -1
Run Code Online (Sandbox Code Playgroud)

其中包括上次提交的gpg信息.

  • `killall gpg-agent && gpg-agent --daemon --use-standard-socket --pinentry-program/usr/local/bin/pinentry`终于为我修好了 (14认同)
  • 嗯...不起作用.仍然在签署xcode时出错. (7认同)
  • 将gpg.program设置为/ usr/local/bin/gpg(没有"1")为我修复它. (5认同)
  • 似乎更新了'gnupg2`,`brew`与符号链接混乱,因此`gpg`被删除了,我使用`brew link --overwrite gnupg2`修复了链接. (5认同)
  • 仅当我使用短 ID `git config --global user.signingkey &lt;short Key ID&gt;` 时,它才对我有用。 (5认同)
  • 在 M1 mac 上,该行应该是 `echo "pinentry-program /opt/homebrew/bin/pinentry-mac" &gt;&gt; ~/.gnupg/gpg-agent.conf` (3认同)
  • 我解决了。总体说明是正确的。问题出在 `echo "pinentry-program /usr/local/bin/pinentry-mac" &gt;&gt; ~/.gnupg/gpg-agent.conf` 行中 — 在盲目复制粘贴之前,检查一下自己,可执行文件在哪里“位于“pinentry-mac”。它是通过 `which`: `which pinentry-mac` 完成的。在我的 M1 mac mini 上,它是“/opt/homebrew/bin/pinentry-mac”!因此,编辑 `~/.gnupg/gpg-agent.conf`,例如使用 sublime text:`subl ~/.gnupg/gpg-agent.conf` 并进行相应的编辑,就像我的情况一样:`pinentry-program /选择/homebrew/bin/pinentry-mac`。这为我解决了问题。 (3认同)
  • 用`echo“测试”| gpg --clearsign` 我收到“gpg:签名失败:设备的 ioctl 不适当” (2认同)
  • 我只做了“killall gpg-agent”,问题就消失了。谢谢@DanBechard (2认同)
  • 从 Catalina (11.1) 开始,“gpg”的自制公式与“gpg2”相同。我怀疑保留“gpg2”是为了向后兼容。您可能想更新您的答案 (2认同)

Kor*_*tor 263

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

export GPG_TTY=$(tty)
Run Code Online (Sandbox Code Playgroud)

请参阅GPG关于常见问题的文档.

  • 如果使用fish,请在您的个人资料中添加`set -x GPG_TTY(tty)`. (12认同)
  • 这就是我 WSL2 所需要的。 (10认同)
  • 我将变量添加到`〜/ .zshrc`,我可以再次提交,现在它正确连接到终端.感谢你的帮助! (5认同)
  • 使用启用了即时提示的 Powerlevel10k 的“zsh”用户请注意,您最终可能会得到“not a tty”值:https://unix.stackexchange.com/a/608921/5095。一个快速的解决方法是使用更快、更安全的方法(在 Zsh 的上下文中):“export GPG_TTY=$TTY”。 (5认同)
  • @brandaemon当然,把它添加到`〜/ .profile`. (2认同)

Bom*_*mbe 153

如果一切都失败了,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
Run Code Online (Sandbox Code Playgroud)

现在手动运行失败命令:

$ gpg -bsau 23810377252EF4C2
gpg: skipped "23810377252EF4C2": Unusable secret key
gpg: signing failed: Unusable secret key
Run Code Online (Sandbox Code Playgroud)

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

  • 很好的调试技巧.+1 (19认同)
  • 好吧,在我的机器上执行 `gpg -bsau &lt;key&gt;` 不会执行任何操作。这是否假设执行时间太长?或者这是否意味着可以使用密钥?@VonC 有什么见解吗? (14认同)
  • 这是唯一正确的答案。更好地了解正在发生的事情,而不是盲目地尝试一百万种不同的可能解决方案 (7认同)
  • 如果您的密钥已过期,您可以按照此处的说明进行更新:/sf/answers/3061000351/ (4认同)
  • 这实际上帮助我解决了自己的问题,并且使用此状态消息可以解决每种类型的问题。+1 (3认同)
  • 我收到“密钥不可用” (3认同)
  • 谢谢你!为我修好了。我的 gpg 代理是运行 gpg 后的一个点发布,所以它很吵闹。运行建议的“gpgconf --kill all”效果很好。谢谢! (3认同)
  • 谢谢!这导致了我的问题。奇怪的是,我的本地`.git / config`在一个项目中指定的`name'与我的签名电子邮件不匹配。那足以拒绝它。 (2认同)
  • 最佳答案!对我来说,这是一个全新的 GPG 设置,因此启用 GIT_TRACE 会让我看到“无密钥”。在运行“git config --global user.signingkey”之后,我就可以签署我的提交了。谢谢 (2认同)

Sha*_*ani 59

我已经度过这段短暂简单的食谱:

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

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
Run Code Online (Sandbox Code Playgroud)

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

no-tty
Run Code Online (Sandbox Code Playgroud)

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

pinentry-program /usr/local/bin/pinentry-mac
Run Code Online (Sandbox Code Playgroud)

  • 在具有原生brew的Apple Silicon上,“pinentry-mac”的路径将是“/opt/homebrew/bin/pinentry-mac” (13认同)
  • 设置配置文件后,我还必须运行`killall gpg-agent`,然后它起作用了! (6认同)
  • 好的,我错过了必须使用的`user.signingkey`. (4认同)
  • 您还能解释这些命令在做什么吗?这将有助于理解。 (2认同)

小智 44

可能有助于杀死gpg-agent可能与旧数据相关的进程.所以新的gpg-agent开始会要求密码

  • 使用`gpg-agent --daemon`启动它 (9认同)
  • 在 ubuntu 上`gpgconf --kill gpg-agent` (7认同)
  • 终止macOS上的进程:`killall gpg-agent` (5认同)
  • 这为我做到了。 (2认同)
  • 我也必须重新启动 gpg-agent (2认同)

Eng*_*ero 28

我见过类似的答案,但与对我有用的完全不同。在 Linux 上,我必须杀死并重新启动我gpg-agent的:

$ pkill gpg-agent
$ gpg-agent --daemon
$ git commit ...
Run Code Online (Sandbox Code Playgroud)

这对我有用。看起来您确实需要根据user.signingkey其他一些评论所说的内容设置您的私钥。

$ git config --global user.signingkey [your_key_hash]
Run Code Online (Sandbox Code Playgroud)

  • 这对我在 MacOS 10.15.6 上有效,并从brew安装了 gpg (GnuPG) 2.2.23。谢谢你的提示! (2认同)

Muh*_*kur 28

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

killall gpg-agent
Run Code Online (Sandbox Code Playgroud)

我认为这只是 gpg 代理的一个错误,杀死它然后再次工作。


小智 25

请按照以下网址设置已签名的提交 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
Run Code Online (Sandbox Code Playgroud)
  1. 然后使用 export GPG_TTY=$(tty)

4.然后再次尝试echo "test" | gpg --clearsign 获得PGP签名。

  1. git config -l | grep gpg

gpg.program = gpg commit.gpgsign = true

6.申请 git commit -S -m "commitMsz"

  • `export GPG_TTY=$(tty)` 就是窍门。将其添加到我的“.zshrc”文件中 (8认同)
  • Ubuntu 20.04 成功。谢谢!这不是第一个提供“export GPG_TTY=$(tty)”的答案。这里的区别是 @jayesh 还提供了一个测试,但没有提供任何关于 gpg2、fish 或 brew 的内容,这些内容与 Ubuntu 中的任何内容都没有关系(?)。这也是一个更新的答案,就我的目的而言,这意味着目前这个答案可能比几年前的答案更好。这篇简短、有效且最新的帖子干得很好。 (2认同)
  • 我确认这适用于 WSL2!在 Git Bash 中我不需要做这个配置,即 GUI 自然出现。然而,在 WSL2 中,尽管通过 X 服务器提供了 GUI 支持,但如果没有“export GPG_TTY=$(tty)”,它就无法工作。这效果很好。 (2认同)
  • 拯救了我的一天(和一夜)。你能说出export GPG_TTY=$(tty) 是什么意思吗? (2认同)

tra*_*sis 22

在 OS X 上,使用gnupg2via brew 我只需要杀死 gpg 代理,有时会发生:

pkill -9 gpg-agent
Run Code Online (Sandbox Code Playgroud)

env根据需要设置变量:

export GPG_TTY=$(tty)
Run Code Online (Sandbox Code Playgroud)

也请参阅常见的 GPG 问题以及这里的答案。

  • 这对我也有用。我创建了一个新别名 `alias fix-gpg='pkill -9 gpg-agent &amp;&amp; export GPG_TTY=$(tty)'`。 (3认同)
  • 这很好用,谢谢。之后甚至不需要设置环境变量。 (2认同)

Geo*_*kas 15

我的两分钱在这里:

当您为gpg-agent创建并添加密钥时,您可以定义一些名为passphrase.现在,passphrase在某些时候到期,并且gpg需要您再次输入它以解锁您的密钥,以便您可以再次开始签名.

当您使用与接口的任何其他程序gpg,gpg的提示您输入您的密码会不会出现(基本上gpg-agent进程化不可能告诉你输入对话框中时stdin).

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

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

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


Gen*_*ani 15

对于在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. 如果要将密钥导出到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 = gent@youremail.com
	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
Run Code Online (Sandbox Code Playgroud)

  • 在.gitconfig中添加'gpsign = true'为我修复了它 (2认同)

Von*_*onC 10

更新2016年10月:问题871确实提到"签署停止在Git 2.9.3中工作"

两天前(2016年10月4日)发布的Git for Windows 2.10.1修复了交换GPG签名提交和标记.

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


原始答案:

阅读" 7.4 Git工具 - 签署您的工作 ",我假设您有" user.signingkey"配置集.

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

登录该文件会显示最近提交的更改af2b21e(Git 2.10)

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

这对于验证本身并不重要:如果验证通过,则pgp签名是好的.
但是如果你还没有真正拥有密钥,并且想要获取它,或者你想要确切地检查哪个密钥用于验证并想要检查它,我们应该更精确地指定密钥.

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

还有提交0581b54,它改变了gpg failed to sign the data错误消息的条件(作为提交0d2b664的补充):

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

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

让我们转换为使用tempfile对象,它为我们处理硬案例,并添加缺少的清理调用.


Sha*_*Koh 9

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

安迪·海登的更新答案应修改如下:

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
Run Code Online (Sandbox Code Playgroud)


luc*_*rot 8

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

试着echo "test" | gpg2 --clearsign看看gpg2是否有效.我发现它是最容易设置的解决方案git config gpg.program gpg,因为它可行.但是你也会以这种方式得到更好的错误 - 例如你需要安装pinentry.


phy*_*att 8

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

   GIT_TRACE=1 git commit -m "a commit message"
Run Code Online (Sandbox Code Playgroud)
   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
Run Code Online (Sandbox Code Playgroud)

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

它变成了,

   gpg --quick-generate-key "full name <your-email@domain.com>"
Run Code Online (Sandbox Code Playgroud)

然后它奏效了.

希望有所帮助.

  • 伙计......你无法想象我花了多少时间试图解决这个问题,直到我得到你的答案......这一直是钥匙的命名......谢谢!谢谢你!谢谢你! (2认同)

gMa*_*ale 7

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

为了看到这一点,我运行了它并确认我的密钥已过期:

gpg --list-keys
Run Code Online (Sandbox Code Playgroud)

为了纠正这个问题,我运行了(使用上一个命令中显示的 ID):

gpg --edit-key <ID>
Run Code Online (Sandbox Code Playgroud)

从那里,我延长了这些说明的有效期key 0key 1遵循这些说明key 0然后归结为打字expire并遵循提示。然后重复key 1

之后,为了测试这个,我跑了:

echo test | gpg --clearsign
Run Code Online (Sandbox Code Playgroud)

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

gpg: 无默认秘钥:无秘钥
gpg:[标准输入]:清除签名失败:没有密钥

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


Shu*_*min 7

我正在使用M1 Mac,我尝试了上述最常见的解决方案,但没有成功,我的问题是这里缺少 GPG 二进制文件 =>usr/local/bin

最初,我通过安装了 GPG brew,并尝试重新安装它,但找不到它存储的二进制文件,后来我从这里安装了 GPG Suite GUI => GPG Suite Tools并且它起作用了。

最后,我可以在 Github 上登录提交并获取验证徽章。


max*_*m10 6

我偶然发现此错误不是因为任何配置问题,而是因为我的密钥已过期。在 OSX 上延长其有效性的最简单方法是打开 GPG 钥匙串应用程序(如果已安装),它会自动提示您延长它。单击两次,即可完成。


Arn*_*rno 5

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

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

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


小智 5

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

git config --global user.email "user@example.com"
Run Code Online (Sandbox Code Playgroud)

  • 就我而言,问题是我在特定存储库中使用公司电子邮件,而我没有为其生成 PGP 密钥。 (2认同)

vis*_*koo 5

我一定是不小心更新了 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.
Run Code Online (Sandbox Code Playgroud)

跑步gpgconf --kill all为我修好了。

希望这可以帮助某人。


Lou*_*ge9 5

可能是挂起的gpg代理。

尝试gpgconf --kill gpg-agent 按照这里的讨论


yeg*_*256 5

就我而言,问题在于gpginside的相对名称~/.gitconfig。我把它改成这样,问题就消失了(Monterey,Macbook M1):

[gpg]
    program = /opt/homebrew/bin/gpg
Run Code Online (Sandbox Code Playgroud)

解释很简单:当git尝试运行时gpg,它会在新的 shell 中运行,而不运行~/.profilePATH为自制程序配置的位置。所以,根本就找不到gpg


sal*_*hin 5

我发现检查git commit幕后情况非常有帮助。运行以下提交,GIT_TRACE=1如下所示:

GIT_TRACE=1 git commit -S -m "MESSAGE"
Run Code Online (Sandbox Code Playgroud)

这将显示 git 在提交时使用的用户名、电子邮件和签名密钥。

就我而言,我发现 git 为签署提交而选择了错误的用户和关键详细信息。我主要打算使用存储库的本地配置而不是全局配置,并将以下内容添加到本地 git 配置(位于“REPO_PATH/.git/config”)中,签署提交以在终端和 VSCode 中工作

[user]
    name = USER NAME
    email = USER EMAIL
    signingKey = SIGNING KEY
Run Code Online (Sandbox Code Playgroud)

还可以通过以下方式进行设置:

git config --local user.name "USER NAME"
git config --local user.email "USER EMAIL"
git config --local user.signingkey "USIGNING KEY"
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

107071 次

最近记录:

6 年 前