Using Command-Line Passphrase Input for GPG with Git (for Windows)
I’m using Git for Windows, and have configured it to sign every single commit and tag using GPG (GnuPG), which uses Pinentry, a program that allows for secure entry of PINs or passphrases.
Every time when I commit my code, a Pinentry window will always popup and ask me for the passphrase to unlock my key. However, the window never gains focus, and I have to move my mouse and click on the input box to start typing, which is quite annoying to me.
A bug report is found on GnuPG’s Phabricator, but seems there’s still no solution or workaround.
Trying to use the “loopback” (command-line) mode of Pinentry
After digging deep into GnuPG’s documentations, I found out that there’s a “loopback” mode of Pinentry, which will redirect the passphrase queries back to the caller (GnuPG), so that the user will be prompted to input the passphrases directly in the command line.
Loopback mode is disabled by default. To enable it, edit the config of GPG agent (
~/.gnupg/gpg-agent.conf) and add the following line.
Tell GPG to reload the config with
gpg-connect-agent reloadagent /bye. After that, you will be able to add
--pinentry-mode loopback to
Looks great. But…
How to use loopback mode when signing commits with Git?
First I thought there might be some Git config that can be used to add extra arguments to GPG. There’s a
gpg.program config for setting a custom program instead of
gpg used by Git. I tried to set it to
gpg --pinentry-mode loopback, but it won’t work, throwing me errors like “cannot spawn gpg –pinentry-mode loopback: No such file or directory“.
Then I wrote a Bash script to serve as a “proxy” for GPG. The script writes simple, just adding the loopback arg and letting all the other args pass through.
Save it somewhere (
~/.gpg-pinetry-loopback for me), grant the execution permission to it with
chmod +x ~/.gpg-pinentry-loopback, and set the full, Windows-style path as the
gpg.program config for Git:
> git config --global gpg.program "C:/Users/beta/.gpg-pinentry-loopback"
Now let’s see if it works.
Wrapping things up
Reload GPG config.
gpg-connect-agent reloadagent /bye
- Create a Bash script at
~/.gpg-pinentry-loopback(or any path you like).
- Grant execution permission to the script. Replace the path with your own.
chmod +x ~/.gpg-pinentry-loopback
- Set the script as the GPG program for Git. Replace the path with your own (full Windows-style path required).
git config --global gpg.program "C:/Users/beta/.gpg-pinentry-loopback"