【问题标题】:Prevent GPG password prompt on Mac在 Mac 上防止 GPG 密码提示
【发布时间】:2017-02-08 09:05:13
【问题描述】:

我正在尝试为 Github 生成一个 gpg,详见此处:https://help.github.com/articles/generating-a-new-gpg-key/

我已经生成了密钥并设置了 ~/.gitconfig 和我的本地 .git/config 以包含

[user]
  email = austin@my_email_address.com
  name = Austin Gibbons
  signingkey = <key_id>
[gpg]
  program = /usr/local/bin/gpg
[commit]
  gpgsign = true

在 ~/.gnupg/gpg.conf 我有

no-emit-version
use-agent

在 ~/.gnupg/gpg-agent.conf 中

default-cache-ttl 28800000
max-cache-ttl 28800000
use-standard-socket
pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac

每次我运行git commit 时都会提示我输入我的 gpg 密码,而我设置的任何内容似乎都无法改变这一点。我不确定如何在我的钥匙圈中设置它,如果有任何建议,我将不胜感激!

我正在运行一个 gpg-agent 守护进程

$ ps aux | grep gpg
austin          63896   0.9  0.0  2432772    676 s010  S+    2:37PM   0:00.00 grep gpg
austin          98503   0.0  0.0  2436440    584   ??  S    10:41AM   0:00.00 /bin/bash /usr/local/MacGPG2/libexec/shutdown-gpg-agent
austin          51417   0.0  0.0  2475748    928   ??  Ss    1:58PM   0:00.45 gpg-agent --daemon

当我添加到 ~/.gnupg/gpg.conf 时

no-tty

我明白了

$ git commit -m "test"
error: gpg failed to sign the data
fatal: failed to write commit object

与其他问题类似:

Git signed commits - How to suppress "You need a passphrase to unlock the secret key..."

我还尝试通过命令行和 gpg-tools 生成密钥

【问题讨论】:

  • 只是为了确定 -- 你是 killall gpg-agent 还是在更改 gpg-agent.conf 后重新启动?
  • 是的 - 每次我在 ~/.gnupg 中进行更改时,我都尝试重新启动 gpg-agent

标签: git gnupg


【解决方案1】:

我遵循了与您所做的类似的过程。 (这是在 OSX 10.10.5 上完成的)

详情如下。


创建 GPG 密钥并将其添加到 Github

首先按照https://help.github.com/articles/generating-a-new-gpg-key/ 上的说明进行操作,在第 1 步中要求下载 GPG 工具。我尝试下载https://sourceforge.net/projects/gpgosx/files/GnuPG-2.1.14.dmg/download,但它并没有出现在PATH中,所以想搜索brew

$ brew search gpg
==> Formulae
gpg  gpg1 gpg2 gpgme libgpg-error

==> Casks
gpg-suite  gpg-suite-nightly  gpg-suite-no-mail  gpg-suite-pinentry gpg-sync

$ brew cask install gpg-suite-no-mail
==> Downloading https://releases.gpgtools.org/GPG_Suite-2019.2.dmg
...... installation log snipped ....

注意:gpg-suite-no-mail 会安装全套 GPG 工具(现在称为 GPG Suite),但 GPG Mail 是一项高级功能。

有了这些,继续按照https://help.github.com/articles/generating-a-new-gpg-key/ 上的说明从 #2 到 #14,然后在我的 Github 帐户中添加一个 4096 位 GPG 密钥。

以下是步骤 #2 到 #9(创建 GPG 密钥)的一些输出:

$ gpg --gen-key
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection?  (Chose DEFAULT)

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: blahblah
Email address: blahblah@blah.blah
Comment:
You selected this USER-ID:
    "blahblah <blahblah@blah.blah>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

You need a Passphrase to protect your secret key.
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
gpg: key ABCDEFG marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   4096R/ABCDEFG 2016-10-03
      Key fingerprint = adf asdf asdf asdf asf asdfas dfasdf
uid       [ultimate] blahblah <blahblah@blah.blah>
sub   4096R/ABCDEFG 2016-10-03

在 GIT 中使用 GPG 密钥来创建和推送签名提交

然后创建并推送一个 签名 提交到 Github:

$ git config --local user.signingkey ABCDEFGHIJKLD2

$ touch test && git add test

$ git -c user.name="blahblah" -c user.email=blahblah@blah.blah commit -S -m "Test GPG"

You need a passphrase to unlock the secret key for
user: "blahblah <blahblah@blah.blah>"
4096-bit RSA key, ID ABCDEFG, created 2016-10-03

[master abcdefg] Test GPG
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test

$ git push
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 956 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To ssh://github.com/someuser/somerepo.git
   abcdefg..abcdeff  master -> master

第一次尝试创建签名提交导致以下弹出窗口:

但是,在我将其保存到钥匙串后,在创建另一个签名提交时并没有再次提示我,在推送提交时,Github 正确地将提交显示为“已验证”:

【讨论】:

  • 嗯,感谢 Ashutosh 的回复 - 当我完成这些步骤时,我从来没有在钥匙串弹出窗口中保存。您知道另一种将其保存在钥匙串中的方法吗?
  • GPGPreferencesStore in OS X Keychain 中还有一个选项。此外,检查GPG Keychain 应用程序是否显示您的密钥可能是值得的。 This (Section 1) 也值得一读。
  • 升级到 Sierra 后我才遇到这个问题
  • 遇到同样的问题不能再提示了!
【解决方案2】:

这里是如何在 Python 2 中做 Ashutosh 的解决方案。(从here 窃取和修改)

import subprocess
import urllib

gpg_agent = subprocess.Popen(["gpg-connect-agent"], stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE)
prompt = urllib.quote('Please enter your password')
cache_id = 'foobar_app1'
command = "GET_PASSPHRASE %s X X %s\n" % (cache_id, prompt)
stdout = gpg_agent.communicate(command)[0]
if gpg_agent.returncode != 0:
    raise Exception("gpg-connect-agent exited %r" %
                    (gpg_agent.returncode,))
elif not stdout.startswith("OK"):
    raise Exception("gpg-agent says: %s" % (stdout.rstrip(),))
else:
    # You'll get an exception here if we get anything we didn't expect.
    passphrase = stdout[3:-1].decode("hex")
    print(passphrase)

【讨论】: