131

I expect the following command to extract the gpg file without asking for password:

  gpg --passphrase 1234 file.gpg

But it asks for the password. Why?

This also have the same behavior:

  gpg --passphrase-file passfile.txt file.gpg

I use Ubuntu with gnome 3, and remember that it was working in Fedora

4
  • 1
    Are you sure gpg run the right command, not an alias nor a wrapper? Try /usr/bin/gpg --passphrase 1234 file.gpg , type gpg , gpg --version and set | grep '^.\{0,9\}PG' Commented Jan 8, 2013 at 20:07
  • Just for the record, if you use the old version of GPG, it should work (on Ubuntu and such, it's the gnupg1 package. However, they discourage using it unless you have to. Commented Aug 23, 2018 at 5:16
  • Also note that in GPG 2.x gpg --list-packets --batch myFile.gpg prompts for a passphrase, while it doesn't in GPG 1.x. That was my problem (in a program that I'm writing), while I thought I had your problem (the --list-packets thing executed first, before attempting to decrypt, and I didn't notice). So, I made a new way to determine if files were encrypted. Commented Aug 24, 2018 at 11:01
  • 1
    If you have gpg --version 2.x (as in Ubuntu 18.04), jump to Xen2050's answer: unix.stackexchange.com/a/415064/237055 Commented Dec 6, 2019 at 9:14

20 Answers 20

105

I am in your exact same boat (it worked on Fedora but not Ubuntu). Here is an apparent work around I discovered:

echo your_password | gpg --batch --yes --passphrase-fd 0 your_file.gpg

Explanation: Passing 0 causes --passphrase-fd to read from STDIN rather than from a file. So, piping the passphrase will get --passphrase-fd to accept your specified password string.

13
  • 29
    adding --batch --yes to the above worked for me.
    – ryantuck
    Commented Oct 29, 2015 at 15:37
  • 2
    Well, with the Ubuntu version of gpg, echo "encrypt me" | gpg --passphrase "mypassphrase" --batch --quiet --yes --no-use-agent -c -o encrypted.gpg seems to work.
    – con-f-use
    Commented Mar 19, 2017 at 7:25
  • 6
    I'm getting Inappropriate ioctl for device with and without --batch here (on gpg (GnuPG) 2.1.18). Commented Dec 17, 2017 at 14:35
  • 3
    @RyanGriggs I don’t think so. echo "hello" | cat and echo "hello"| cat both yield the same string. Commented Feb 23, 2019 at 15:04
  • 8
    This works for me cat your-passphrase-file.txt | gpg --pinentry-mode loopback --passphrase-fd 0 --sign your-file-to-sign.txt
    – Elshan
    Commented Apr 25, 2020 at 18:43
75
+25

Upgraded 2017-12-04. (Adding --batch in order to prevent passphrase prompt)

You may have to add --batch option:

And. if you use recipient key pair you may have to add --pinentry-mode loopback too.

From version 2 of GPG, the option --batch is needed to ensure no prompt... Ok, looking that:

$ gpg --version
gpg (GnuPG) 2.1.18
libgcrypt 1.7.6-beta
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/user /.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Trying:

$ newdir=$(mktemp -d)
$ cd $newdir
$ seq 1 10 | gpg -c --batch --passphrase 1234 -o file.gpg -
$ ls -ltr
total 4
-rw-r--r-- 1 user  user  91 Dec  4 15:42 file.gpg
$ hd file.gpg 
00000000  8c 0d 04 07 03 02 ea fa  d0 d3 2b 9a ea 06 df d2  |..........+.....|
00000010  4a 01 ed 50 74 ff 27 45  0e 6c 94 74 db e9 8a a5  |J..Pt.'E.l.t....|
00000020  03 9f 67 a0 73 97 e9 15  6b 56 a0 f0 88 71 85 a8  |..g.s...kV...q..|
00000030  dc 41 71 9f fa 3b f9 9d  af ac 80 eb f4 f7 28 19  |.Aq..;........(.|
00000040  9f be 75 47 e6 d8 00 3e  f6 60 f1 00 5e 63 57 ef  |..uG...>.`..^cW.|
00000050  14 c3 4b 20 ff 94 03 03  c1 fc 98                 |..K .......|
0000005b

sound good! Well, now:

$ gpg -d --batch --passphrase 1234 file.gpg
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
1
2
3
4
5
6
7
8
9
10

If no -d parameter is given (same syntaxe as SO's question), decrypted datas from file.gpg will be extracted to a new file:

$ gpg --batch --passphrase 1234 file.gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: AES encrypted data
gpg: encrypted with 1 passphrase

$ ls -ltr
total 8
-rw-r--r-- 1 user  user  91 Dec  4 15:42 file.gpg
-rw-r--r-- 1 user  user  21 Dec  4 15:44 file

$ cat file
1
2
3
4
5
6
7
8
9
10

This work well!

$ cd -
$ rm -fR $newdir
$ unset newdir

Full sample recipient keyfile:

First create a temporary environment

newdir=$(mktemp -d)
cd $newdir
export GNUPGHOME=$newdir
echo YourPassword >password.txt
gpgconf --kill gpg-agent  # Required, if agent_genkey fail...
gpg --generate-key --batch <<eoGpgConf
    %echo Started!
    Key-Type: default
    Key-Length: default
    Subkey-Type: default
    Name-Real: Full Name There
    Name-Comment: Something funny
    Name-Email: [email protected]
    Expire-Date: 0
    Passphrase: $(<password.txt)
    %commit
    %echo Done.
eoGpgConf
gpg: keybox '/tmp/tmp.xU5Ldyr4iB/pubring.kbx' created
gpg: Started!
gpg: agent_genkey failed: No such file or directory
gpg: key generation failed: No such file or directory
gpg: Done.

Hmm.

gpgconf --kill gpg-agent
    gpg --generate-key --batch <<eoGpgConf
    %echo Started!
    ...
eoGpgConf
gpg: Started!
gpg: key 43E6B96CAFABDEDF marked as ultimately trusted
gpg: directory '/tmp/tmp.xU5Ldyr4iB/openpgp-revocs.d' created
gpg: revocation certificate stored as '/tmp/tmp.xU5Ldyr4iB/openpgp-revocs.d/DF223E1612CF917DC3BD42AA43E6B96CAFABDEDF.rev'
gpg: Done.

Get Key ID

Then now

gpg -k
/tmp/tmp.xU5Ldyr4iB/pubring.kbx
-------------------------------
pub   rsa3072 2020-06-19 [SC]
      DF223E1612CF917DC3BD42AA43E6B96CAFABDEDF
uid           [ultimate] Full Name There (Something funny) <[email protected]>
sub   rsa3072 2020-06-19 [E]

( The last 8char from pub fingerprint could be used as key alias. )

gpg -k [email protected]| sed -e '/^pub/{N;s/.*\(.\{16\}\)/\1/;p;s/^.\{8\}//;q};d' 
43E6B96CAFABDEDF
AFABDEDF

Or even retrieving into a variable, using --with-colons.

while IFS=: read -r typeOfRec _ _ _ keyId _; do
    case $typeOfRec in pub ) break ;; esac
done < <(gpg  --with-colons -k [email protected] )
declare -p keyId 
declare -- keyId="43E6B96CAFABDEDF"

Encrypt

Ok, now!

seq -f "%'8g" 990 5 1015 |
    gpg --batch --armor --recipient "$keyId" --encrypt --output file.gpg

Will give something like:

cat file.gpg
-----BEGIN PGP MESSAGE-----

hQEOA5BNpEVKPGsfEAP/XutJp7ME3I1MqG0vZyIS8w+npPQMPicIpQUwM4OVO1rX
2lhrymp0zGqxAH7s9Dh9YJNRA/9zYCO4/vghtnnl/zg10vILs9btgLXY+aupgoQ9
nifnVC8JJ1DC+hZZrIHyzS73BsjufWhpbwURYc7EgIMGKu2TRiy5I8+0aZ4zAtID
/ApL0sTBQ9hqmIatzaYbX9ajmDf1vvtE2/s3MUFA/hIqew2MVMhlb4RjyT7ix03P
LmCH2Mfy88VGr59eSUoZq+CPMDSZpXxbE2LfyPHYsObraO+a6FdVHhj2xcw/tnDO
TcNHTKnTRJSb9sfLAtJmE9eaxebkl27T+UvqyJUG4dgu0lABadboNaEidlrCYLNi
icR19UX0G7E50+i3iKvw0u81YtciYyOnpHvgazb5QbqJNN5P8izC4J3FqW7HaTDI
xnf+8IaX2Vqrq5+k4qLR7h5Vcw==
=1fb5
-----END PGP MESSAGE-----

Note: From version >=2.2 of gpg``--batch is not required anymore:

seq -f "%'8g" 990 5 1015 |
    gpg -aer "$keyId" >file.gpg

Will do near same effect.

Decrypt

Then

gpg --decrypt --pinentry-mode loopback --passphrase-file password.txt --batch file.gpg

or

gpg -d --pinentry-mode loopback --passphrase-file password.txt --batch file.gpg

will produce:

gpg: encrypted with 3072-bit RSA key, ID 58020687E0746339, created 2020-06-19
      "Full Name There (Something funny) <[email protected]>"
     990
     995
   1'000
   1'005
   1'010
   1'015

But, from version >=2.2 of gpg, you could use:

gpg -qd --passphrase "$(<password.txt)" file.gpg
     990
     995
   1'000
   1'005
   1'010
   1'015
12
  • You are not getting the warning "gpg: gpg-agent is not available in this session" so you probably have the passphrase stored in the agent, perhaps? Commented Aug 20, 2015 at 16:32
  • @AsfandYarQazi No, the passphrase is entered in command line. Commented Aug 23, 2015 at 17:10
  • This answer worked for me. Ubuntu with gpg 1.4.16. The --passphrase parameter works for batch operations, and doesn't prompt for a password. Commented Apr 28, 2016 at 0:27
  • 7
    See lower answer. The key is --pinentry-mode loopback. It works!
    – yahermann
    Commented Jan 7, 2019 at 17:34
  • 1
    This still wants a passphrase(TUI showed up) and locked down my terminal
    – alper
    Commented Jun 18, 2020 at 11:25
60

For gpg version 2.x you don't need to use --batch, just

--pinentry-mode loopback  

works with --passphrase & --passphrase-file, and will let you enter new info, in case of filename conflicts for example:

gpg --pinentry-mode loopback --passphrase-file=file encrypted.gpg

...
File 'encrypted' exists. Overwrite? (y/N)n
Enter new filename: f2

unlike --batch that will quickly fail, saying ...failed: File exists

(tested on Debian Stable/Stretch's gpg 2.1.18. This behaviour of ignoring important --passphrase options really should be a bug, if it isn't already)

6
  • 2
    This works nicely also on Ubuntu 18.04 Bionic with gpg (GnuPG) 2.2.4 Commented May 31, 2018 at 10:52
  • This works on MacOS after installing gpg with homebrew
    – Joel
    Commented Feb 15, 2019 at 18:42
  • 2
    This works for me cat your-passphrase-file.txt | gpg --pinentry-mode loopback --passphrase-fd 0 --sign your-file-to-sign.txt
    – Elshan
    Commented Apr 25, 2020 at 18:42
  • Thank you, it also works for decryption as well
    – alper
    Commented Jun 18, 2020 at 12:13
  • Confirm that it works for gpg 2.2.19 in ubuntu 20.04.
    – zhihong
    Commented Jan 22 at 13:31
19

It sounds like you're using gpg2. You need to throw in the --batch option as well. (If you're planning to add this to a script, you'll also want to add in --no-tty and probably --yes.)

5
  • 3
    It's 1.4. using --batch has no effect.
    – Omid
    Commented Jan 4, 2013 at 10:11
  • Sorry then @Nima. I don't know what to tell you. With GnuPG v1.4 you shouldn't need to do anything else to pass the passphrase in with either of those options.
    – rsaw
    Commented Jan 4, 2013 at 15:19
  • Good note, @rsaw, helped me prevent password prompts (and slightly less elegant echo/STDIN option).
    – ryanm
    Commented Oct 3, 2016 at 16:39
  • --batch helped even in windows. woo hoo.
    – Sin
    Commented Jan 12, 2017 at 1:25
  • --yes wasn't necessary for me. The other two were essential though. Commented May 13, 2021 at 4:45
14

If using gpg (GnuPG) 2.2.7 According to the man page,

--passphrase-fd n

Read the passphrase from file descriptor n. Only the first line will be read from file descriptor n. If you use 0 for n, the passphrase will be read from STDIN. This can only be used if only one passphrase is supplied.

--passphrase-file file

Read the passphrase from file file. Only the first line will be read from file file. This can only be used if only one passphrase is supplied. Obviously, a passphrase stored in a file is of questionable security if other users can read this file. Don't use this option if you can avoid it.

--passphrase string

Use string as the passphrase. This can only be used if only one passphrase is supplied. Obviously, this is of very questionable security on a multi-user system. Don't use this option if you can avoid it.

add --pinentry-mode loopback in order to work

Note that since Version 2.0 this passphrase is only used if the option --batch has also been given. Since Version 2.1 the --pinentry-mode also needs to be set to loopback.

For example:

gpg --batch --yes --passphrase="pw" --pinentry-mode loopback -o out -d in
1
  • Are both the --batch and --pinentry-mode loopback options needed for any --passphrase... option to work? On v.2.1.18 the info page says the same thing (but not the man page) about batch & pinentry needed, but still works with only --pinentry... If both really are needed for v.2.2.7 then things are getting ridiculous, developers are introducing serious bugs on purpose
    – Xen2050
    Commented Dec 16, 2018 at 16:18
11

for me, adding "--no-use-agent" solved this for "gpg (GnuPG) 1.4.16":

date > foo
echo pass > passphrase
# w/o --no-use-agent
> rm -f foo.gpg; gpg --cipher-algo aes256 --output foo.gpg --passphrase-file ./passphrase --batch --yes --symmetric foo
gpg: gpg-agent is not available in this session
gpg: can't query passphrase in batch mode
gpg: error creating passphrase: invalid passphrase
gpg: symmetric encryption of `foo' failed: invalid passphrase


> rm -f foo.gpg; gpg --cipher-algo aes256 --output foo.gpg --passphrase-file ./passphrase --batch --yes --no-use-agent --symmetric foo
> ls -al
total 20
drwxr-xr-x  2 root root 4096 Aug 22 13:59 .
drwx------ 18 root root 4096 Aug 22 13:58 ..
-rw-r--r--  1 root root   30 Aug 22 13:58 foo
-rw-r--r--  1 root root  103 Aug 22 13:59 foo.gpg
-rw-r--r--  1 root root    5 Aug 22 13:58 passphrase
8
read -sp "Enter passphrase: " pass
echo "${pass}" | gpg --batch --no-tty --yes --passphrase-fd 0 --symmetric -o /path/to/saved/file.jpg.gpg /path/to/file.jpg
echo "${pass}" | gpg --batch --no-tty --yes --passphrase-fd 0 --decrypt -o /path/to/decrypted/file.jpg /path/to/encrypted/file.jpg.gpg
6

It worked like magic for me:

echo "YOUR_PASS_PHRASE" | gpg --batch --yes  --passphrase-fd 0 /home/somewhere/your_file.pgp
1
  • error: gpg: no valid OpenPGP data found. gpg: processing message failed: eof. Any ideas? Commented Mar 6, 2018 at 3:18
3

have you tried doing :

gpg --batch --passphrase-fd 0 --decrypt-files *.gpg
gpg --passphrase-fd 0 1234 file.gpg 

Source: Here

3

As mentioned in man gpg following option can be used

--pinentry-mode mode Set the pinentry mode to mode. Allowed values for mode are:

          default
                 Use the default of the agent, which is ask.

          ask    Force the use of the Pinentry.

          cancel Emulate use of Pinentry's cancel button.

          error  Return a Pinentry error (``No Pinentry'').

          loopback
                 Redirect Pinentry queries to the caller.  Note that in contrast to Pinentry the user is not prompted again if he enters a bad password.

So default behaviour of gpg is to prompt user for passphrase, if change this user agent mode to " --pinentry-mode loopback " It works perfectly fine. complete command

gpg --pinentry-mode loopback --passphrase <passphrase> -d <file to decrypt>
2

I think that a quite secure method to pass the password to the command line is this:

gpg --passphrase-file <(echo password) --batch --output outfile -c file

What this will do is to spawn the "echo" command and pass a file descriptor as a path name to gpg (e.g. /dev/fd/63). gpg will then read the key from there. In the mean time, the echo command should run in parallel and should finish instantly, leaving the key on the buffer of the fd.

Benefits are:

  • The gpg command will not have the password on its command line
  • The echo will be short lived. In fact, it should be almost instant
  • The password will never reside on the disk, there won't be a file to be deleted and if the command is interrupted there will be no leftovers
2

This works on Ubuntu 20.04 and can be used in bash scripts

echo "password" | gpg -c --pinentry-mode loopback --passphrase-fd 0 ./file_to_encrypt

and gives as output

./file_to_encrypt.gpg

Tested using gpg (GnuPG) 2.2.19 and libgcrypt 1.8.5

1

You won't believe me when I tell you that on ubuntu gpg tries to ask your password if $DISPLAY is set and takes it from commandline --password if you unset it. This works as expected:

DISPLAY=    gpg --symmetric --passphrase pass --batch

Just another example of over engineering I guess.

1

Here's a link to a stackoverflow answer that maybe of further assistance; I have a project that does bulk decryption/encryption, and due to GnuPG being very strict about passphrases, learned the hard way that --passphrase only works on rare occasions. Instead consider the --passphrase-fd option to be more reliable.

This script makes proper use of the --passphrase -fd option, and has been tested publicly via Travis-CI where you can find logs of it in action.

Now I ain't going to just post links to an answer without providing some example code here, so here's an updated "stand alone" script you can play with:

#!/usr/bin/env bash
# Set some variables for easy modding
Var_fd='9'
Var_pass="/path/to/passphrase.file"
Var_gpg_opts="--passphrase-fd ${Var_fd} --decrypt"
Var_output_location="out.txt"
Arr_string=( "$@" )
# Open file descriptor and shove the passphrase file into it
if [ -f "${Var_pass}" ]; then
    exec ${Var_fd}<"${Var_pass}"
else
    exec ${Var_fd}<(echo "${Var_pass}")
fi
# Pipe input array though gpg and append to output file
cat <<<"${Arr_string[*]}" | $(which gpg) ${Var_gpg_opts} >> ${Var_output_location}
# Do not forget to close the file descriptor
exec ${Var_fd}>&-

While the above isn't as fancy as the linked protect at GitHub it should be even more functional than the answer linked at the beginning of this post.

Happy hacking.

0

One simple method I found working on a linux machine is : 1) import key to gpg :=> shell> gpg —import private_key.key

2) decrypt giving outfile name :=> shell> gpg —output -d

2.1) Giving above command will prompt you to enter paraphrase. Enter the paraphrase and it will decrypt the gpg file.

0
gpg2 -se --passphrase yourpassword --batch --yes -r [email protected] filename
2
  • 2
    it would be nice if you could explain why this should fix the problem
    – Zanna
    Commented Feb 27, 2017 at 8:57
  • 2
    While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, not just the person asking now! Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply. Commented Feb 27, 2017 at 10:23
0

Put at the end of ~/.gnupg/gpg.conf:

use-agent
pinentry-mode loopback

Put at the end of (maybe new) file ~/.gnupg/gpg-agent.conf:

allow-loopback-pinentry

And then run this command:

echo RELOADAGENT | gpg-connect-agent

Now you are able to run this without asking password:

echo "$1" | gpg2 --trust-model always --clearsign --batch --no-tty --quiet --no-verbose --yes -u $2 --digest-algo SHA512
--s2k-digest-algo SHA512 --passphrase "$3"

Where $1 is the text to be encrypted, $2 is the user ID and $3 the password.

Note: I can't remember why it works, but it works. If you know the details, please edit and insert here.

0

for Ubuntu 18.04 this worked for me-

encrypt:

pass='123'

gpg -c --batch --passphrase "$pass" some-file.tgz

decrypt:

gpg some-file.tgz.gpg
0

Even I was facing the same issue. But none of the commands mentioned here didn't work and I also checked different answers with different commands but nothing worked.

I was on Ubuntu 20.04.1 LTS

After a lot of head bashing and experimenting somehow this

gpg --pinentry-mode loopback --passphrase-file=passphrase.txt --decrypt-files my-encrypted-gpg-file.gpg

passphrase.txt file contains your passphrase.txt, obvisuosly.

Hope it'll help.

0

You can preset the passphrase with gpg-preset-passphrase (useful for --sign, --clearsign, etc.):

apt install -y gpg gpg-agent
mkdir -p ~/.gnupg
echo allow-preset-passphrase| tee -a   ~/.gnupg/gpg-agent.conf
gpg-agent --daemon ||  gpg-connect-agent reloadagent /bye  # may already be running
/usr/lib/gnupg2/gpg-preset-passphrase  -P MyS3Cr3T -c    AD91A6ADEA004BDB931317707EE9C281717EE410  # caching the passphrase

gpg --import --allow-secret-key --batch my_secret_key.gpg  # importing works with cached passphrase
gpg  --output signed_file.gpg -u E4D76E372E6B3E413D6C9B1DAD6AE9137402C881 --clearsign file_to_sign.txt  # signing works with cached passphrase

With following key material:

gpg -K --with-keygrip
/root/.gnupg/pubring.kbx
------------------------
sec   rsa4096 2021-09-27 [SC]
      E4D76E372E6B3E413D6C9B1DAD6AE9137402C881
      Keygrip = AD91A6ADEA004BDB931317707EE9C281717EE410
uid           [ unknown] my super key <[email protected]>
ssb   rsa4096 2021-09-27 [E]
      Keygrip = 11981E8164AE2A66B09D14E14A83791A9BCDE9BF

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .