23

I'm trying to start signing Git commits. I setup a GPG key with keybase.io and have it synced on my local machine and on my Git server. Now, I'm trying to solve the problem of typing the key passphrase on every single commit.

PS> git commit -m "testing" --allow-empty

You need a passphrase to unlock the secret key for
user: "keybase.io/anthonymastrean <anthonymastrean@keybase.io>"
2048-bit RSA key, ID AD9184C0, created 2015-04-14 (main key ID 293FEB8B)

Enter passphrase:

As I understand it, I need something like gpg-agent installed. I'm on Windows 10 Pro 1803, so I'm looking at Gpg4win (recommend by GitHub and others). I installed it via Chocolatey, so I have the complete default installation.

However, I can't figure out how to get gpg-agent to start caching my passphrase. I'm prompted every time I commit.

The gpg-agent says it's running

PS> gpg-agent
gpg-agent[4644]: gpg-agent running and available

I've this gpg-connect-agent thing, but I don't know what to do with it.

PS> gpg-connect-agent.exe
> help
# NOP
# CANCEL
# OPTION
# BYE
# AUTH
# RESET
# END
# HELP
# GETEVENTCOUNTER
# ISTRUSTED <hexstring_with_fingerprint>
# HAVEKEY <hexstrings_with_keygrips>
# KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>
# SIGKEY <hexstring_with_keygrip>
# SETKEY
# SETKEYDESC plus_percent_escaped_string
# SETHASH (--hash=<name>)|(<algonumber>) <hexstring>
# PKSIGN [<options>] [<cache_nonce>]
# PKDECRYPT [<options>]
# GENKEY [--no-protection] [--preset] [--inq-passwd]
# READKEY <hexstring_with_keygrip>
# GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]
# PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]
# CLEAR_PASSPHRASE [--mode=normal] <cache_id>
# GET_CONFIRMATION <description>
# LISTTRUSTED
# MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>
# LEARN [--send] [--sendinfo] [--force]
# PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset]
# INPUT
# OUTPUT
# SCD <commands to pass to the scdaemon>
# KEYWRAP_KEY [--clear] <mode>
# IMPORT_KEY [--unattended] [--force] [<cache_nonce>]
# EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>
# DELETE_KEY [--force|--stub-only] <hexstring_with_keygrip>
# GETVAL <key>
# PUTVAL <key> [<percent_escaped_value>]
# UPDATESTARTUPTTY
# KILLAGENT
# RELOADAGENT
# GETINFO <what>
# KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>
OK

I see the man page talks about how to start the gpg-agent in a Bash session, but I'm not sure how to translate that to Windows and have it work across cmd.exe and PowerShell.

https://linux.die.net/man/1/gpg-agent

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188

3 Answers3

31
  1. You can use gpgconf --launch gpg-agent to make gpg-agent running in background on Windows.

  2. To make gpg-agent auto-running when I logged in, I add a task in Task Scheduler:

gpg-agent-autostart

  1. To expand the expiry on the passphrase, add these line to gpg-agent.conf:

    default-cache-ttl 34560000
    
    max-cache-ttl 34560000
    

I tried to set the number to 999999999, but it didn't work at all

You can find the location of gpg-agent.conf with this command:

$ gpgconf.exe --list-dirs

sysconfdir:C%3a\ProgramData\GNU\etc\gnupg
bindir:C%3a\Program Files (x86)\GnuPG\bin
libexecdir:C%3a\Program Files (x86)\GnuPG\bin
libdir:C%3a\Program Files (x86)\GnuPG\lib\gnupg
datadir:C%3a\Program Files (x86)\GnuPG\share\gnupg
localedir:C%3a\Program Files (x86)\GnuPG\share\locale
socketdir:C%3a\Users\Jerry\AppData\Roaming\gnupg
dirmngr-socket:C%3a\Users\Jerry\AppData\Roaming\gnupg\S.dirmngr
agent-ssh-socket:C%3a\Users\Jerry\AppData\Roaming\gnupg\S.gpg-agent.ssh
agent-extra-socket:C%3a\Users\Jerry\AppData\Roaming\gnupg\S.gpg-agent.extra
agent-browser-socket:C%3a\Users\Jerry\AppData\Roaming\gnupg\S.gpg-agent.browser
agent-socket:C%3a\Users\Jerry\AppData\Roaming\gnupg\S.gpg-agent
homedir:C%3a\Users\Jerry\AppData\Roaming\gnupg

gpg-agent.conf is in homedir

Tao Zhu
  • 749
  • 6
  • 12
  • Step 1 helped, but I needed more. Maybe this is a change to gpg4win but this process finally worked for me using Administrator Power Shell windows. – James Dec 12 '22 at 23:05
20

I needed to inform git of the gpg program that I've installed, which itself knows about the gpg-agent that it should use.

PS> git config --global gpg.program $(Resolve-Path (Get-Command gpg | Select-Object -Expand Source) | Select-Object -Expand Path)

After setting this configuration, the "PIN Entry" dialog for Gpg4win pops up!

enter image description here

I might be missing something as far as automatically starting the gpg-agent or understanding the session lifecycle, but I'll come back with more details.

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
  • Am I the only one that doesn't understand this answer the least? Question was connecting to a Linux remote from a Windows box. Which git program is given the above path to the gpg installation? The remote or the local box? When and how is the local git executable invoked at all? Doesn't the remote gpg executable have to connect to the local keyring? – Meteorhead Feb 22 '21 at 13:37
  • 1
    @Meteorhead, I think, the problem is "gpg-agent on Windows caches Passphrase only for 10 minutes" and Anthony wants to force it to remember passphrase for GPG key for a longer period of time, and ideally forever, to avoid entering passphrase for each commit. It's really annoying (I ran into this problem today =) – hotenov Mar 24 '21 at 17:09
8

In addition to the Tao Zhu's answer,
you can specify passphrase (PIN) expire lifetime without config files, in GUI key manager Kleopatra, which comes with Gpg4win:

Check it during installing Gpg4win (installer in Russian): enter image description here

Find it in Start menu and run.
Go to menu: Settings - Configure Kleopatra...
enter image description here

Switch to GnuPG System tab, then Private Keys tab
Change default values to yours for two settings Expire cached PINs after N seconds and Set maximum PIN cache lifetime to N seconds, I set this:
enter image description here

Big values let you to avoid frequent and annoying entering passphrase for GPG key on each git commit during a day (until next Windows reboot or expiring specified time)

Unfortunately, I haven't found a way to preserve the passphrase between sessions (reboots) yet either.

hotenov
  • 911
  • 1
  • 11
  • 17
  • This is the clearest answer to "How to make Git remember my GPG passphrase between commits" I have yet found. Still looking, but this will do much more nicely than my current setup works. I am looking for a _Windows centric_ solution that makes use of out-of-the-box configuration provided by Windows as best as it can be done. This is near the mark (conf files are fine, but this is easier for me to remember). – d3r3kk Feb 22 '23 at 21:47