135

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

21 Answers 21

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
  • 30
    adding --batch --yes to the above worked for me. 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. Commented Mar 19, 2017 at 7:25
  • 7
    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
  • 4
    @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
  • 9
    This works for me cat your-passphrase-file.txt | gpg --pinentry-mode loopback --passphrase-fd 0 --sign your-file-to-sign.txt 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! Commented Jan 7, 2019 at 17:34
  • 1
    This still wants a passphrase(TUI showed up) and locked down my terminal 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 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 Commented Apr 25, 2020 at 18:42
  • Thank you, it also works for decryption as well Commented Jun 18, 2020 at 12:13
  • Confirm that it works for gpg 2.2.19 in ubuntu 20.04. Commented Jan 22, 2024 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. 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. Commented Jan 4, 2013 at 15:19
  • Good note, @rsaw, helped me prevent password prompts (and slightly less elegant echo/STDIN option). Commented Oct 3, 2016 at 16:39
  • --batch helped even in windows. woo hoo. 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 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.

1
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 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
1

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

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

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

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 
0

Just gotta add some flags

you can either add --pinentry-mode loopback or --batch and it should work!

1
  • your answer is duplicated of some other answers Commented Nov 23, 2024 at 13:54

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.