I'm trying to figure out a way to change the password of a file that is symmetrically encrypted by GPG without using a temporary file or a shell variable. I know I could do this in a shell function with a variable but I'd like to do it on the command line if possible.
I think this should be possible because GPG will encrypt incoming streams with gpg --symmetric -o example.gpg
and because GPG will send decrypted output to STDOUT with gpg --decrypt
.
But this doesn't work properly:
gpg --decrypt example.gpg | gpg --symmetric -o new.gpg
I think my understanding of the shell order of operations and redirection is wrong. Especially because the shell output has more than one Enter passphrase:
prompts at a time.
Here is the initial interactive response after entering the piped commands:
localhost ~% gpg --decrypt example.gpg | gpg --symmetric -o example.gpg
gpg: CAST5 encrypted data
Enter passphrase: Enter passphrase
After that, I get a variety of password prompts... sometimes I am asked for the decryption password, then I can type the new password in visible plain text, then the new password confirmation which is hidden. Sometimes, I get the new password dialogue before I am asked for the decryption password.
I think there is a race condition.
Any advice?
You need to non-interactively tell the first gpg command what the decryption passphrase is.
With gpg2 (most modern Linux distros ship with this) it could look like this:
gpg --decrypt --batch --passphrase 'original passwd' example.gpg | gpg --symmetric -o new_example.gpg
With gpg1, you would use --no-use-agent
instead of --batch
, e.g.:
gpg -d --no-use-agent --passphrase 'original passwd' example.gpg | gpg -co new_example.gpg
Note: Depending on your version of gpg and how it's configured, you might also have to specify the passphrase in the same way for the second gpg command.
When you put together a commandline with pipes, your shell starts all the commands at the same time after setting up pipes to connect each one (to allow stdout
of each command to be sent to stdin
of the next).
Do not write to the same file you're reading from. It will almost never work out how you want.
On a multi-user system it's a bad idea to use gpg's --passphrase
option, since it makes the passphrase available for inspection by anyone on the system (anyone can run a ps
command and see the passphrase while the gpg
command is running). Furthermore, the passphrase is then saved in your shell history. Yikes. If that's a problem, use --passphrase-fd
or --passphrase-file
.