Using a passphrase FD from variable and piped data for encryption

Brett Cave brett at
Tue Apr 19 12:33:42 CEST 2016

On Tue, Apr 19, 2016 at 11:59 AM, Peter Lebbing <peter at>

> On 19/04/16 09:42, Brett Cave wrote:
> > Hi all, I'm wondering if anyone uses gpg piping data to it (on a *nix
> > To create an archive, and then encrypt it using a variable in 2 steps:
> > tar zxf dir.tgz dir
> > echo $PASSPHRASE | gpg -c --passphrase-fd 0 -o dir.tgz.gpg dir.tgz
> >
> > This way, the passphrase is never written to the fs and does not show up
> > in the process list - it is only in-memory.
> That doesn't seem to be the case, though. $PASSPHRASE is expanded and
> fed as an argument to echo. For instance:

Yes, it is for the duration of the echo command, but not for the duration
of the gpg run:

$ tar zcf - somebigdir | gpg -c --passphrase-fd 0 -o test.tgz.gpg  1<
<(echo foo)
^Z  (ctrl + z)
[1]+ Stopped tar.. etc
$ ps faux | egrep 'foo|echo'
  # only matches the grep, there's no echo process running any more
$ ps faux | grep gpg
  # gpg command found running without passphrase, e.g. pid 2023
$ lsof -p 2023
  # libraries, binary, pipes and output files open - no passphrase files

The window to grab the passphrase:
$ time echo foo

real    0m0.000s
user    0m0.000s
sys     0m0.000s

> $ ARGS=f
> $ ps $ARGS
> [...]
> 26958 pts/1    Ss     0:01 /bin/bash
> 27915 pts/1    R+     0:00  \_ ps f
> [...]
> In addition, there's a good chance your environment variable ends up in
> your swap space.

1 of the flaws of this approach, unless of course kernel swappiness is

> > But how can it be done from a variable?
> I'm certainly not suggesting you use this method, but out of an
> academical interest, I got it to work with:
> $ tar zcf - . | gpg -c --passphrase-fd 3 -o dir.tgz.gpg 3< <(echo test)

ah - I was trying `3< $(echo test)` - needed the double redirect. Thanks!

> I'm redirecting twice. First, I redirect "echo test" to an FD or FIFO of
> Bash's choosing. Then I connect that to fd 3, so I can name fd 3 as the
> passphrase-fd. <(echo test) is expanded to a filename, either of the
> form /dev/fd/X or of some named FIFO created by bash, if I understand
> the Bash manual correctly. The space between the two less-than's is
> necessary.
> > [...] this is purely for "because I want to know
> > how to do it this way" sort of question).
> Which was my motivation exactly :).
> Oh, by the way, your plaintext was already on disk. The only reason to
> worry about the passphrase being on disk is that you might reuse the
> passphrase, right?

If the plaintext is never persisted and the passphrase isn't either /
available from the process list... For the sake of simplicity / example, I
hypothetically referred to a source directory with tar.

For practical purposes, this approach could be used with remote service
data, where the plaintext and plain key is never written to disk (e.g. http
client that invokes a remote call to dump config data, a mysqldump from a
remote server, etc). As far as symmetric encryption goes, not having
plaintext or plainkey ever persisted or viewable is a little more secure (a
compromise would require memory access or network packet sniffing if
remote), although understandably still flawed.

> Asymmetric crypto would nicely avoid the issue by never needing the
> secret part to encrypt data in the first place.

> HTH,

Thanks, helped plenty :)

> Peter.
> --
> I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
> You can send me encrypted mail if you want some privacy.
> My key is available at <
> >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/attachments/20160419/e7705f25/attachment.html>

More information about the Gnupg-users mailing list