[Cryptography] Does it make sense to pipe yescrypt/Argon2id as passphrase for gpg?

Philippe Cerfon philcerf at gmail.com
Mon Aug 23 16:45:01 EDT 2021


Hey.

I've already asked the following on the gnupg-users mailing list
(https://lists.gnupg.org/pipermail/gnupg-users/2021-August/065398.html)
but it seems no one was able to give an answer.


I would like to use gpg's symmetric encryption feature but with
passphrase hashing from either yescrypt or Argon2id.

Neither of them seem to be natively supported, so I wondered whether
the following would actually work out as I have it in mind.


To my understanding a KDF like yescrypt or what gpg uses
("String-to-Key") has these purposes:

1. obtain a key in a format that can be used for the cipher (like
having the proper length or so)
2. protect against certain attacks like dictionary-attacks by adding
e.g. a salt
3. give some protection of low-entropy passphrases by making the
derivation more expensive to an attacker (e.g. CPU or memory-wise)


So as far as I understand, if I'd have a high-entropy passphrase, e.g.
something gained from:
dd if=/dev/random of=key bs=1 count=512
I wouldn't need the KDF at all, at least not with respect to point 3
above, right?



I tried to find out what gpg does here and it seems it's one of the following:
A. When doing just --symmetric, it applies that String-to-Key function
to the passphrase and uses the result directly as symmetric key for
the file.
B. When doing --symmetric and --encrypt, it somehow creates a key
for the file (/dev/random?), and encrypts that with the KDF derived
key and with the pubkey.

(The relevant section of the standard seems to be
https://datatracker.ietf.org/doc/html/rfc4880#section-5.3 )


And for the KDF it seems to allow specifying the iterations
(--s2k-count), and cipher (--s2k-cipher-algo) and hash
(--s2k-digest-algo).


Is --s2k-cipher-algo even used in (A)? And --s2k-digest-algo in (B)?




Now for my original goal of using yescrypt or Argon2id with gpg, would
the following work out and improve security?

read -rs -p 'Enter passphrase: ' PASSPHRASE

printf '%s' "${PASSPHRASE}"  |  argon2 mysaltvalue -id -r  |  gpg
--passphrase-fd 0 --symmetric ...


unset PASSPHRASE


While this works, I'm not so sure whether it actually gives a security
benefit in the cases (A) and (B) above, because there's still
String-to-key in between with whatever cipher, digest and iteration
count.

Wouldn't an attacker simply focus on that element of the chain?
Or do I actually win something, cause the derivation from the
passphrase is now pretty strong with Argon2id or yescrypt and all gpg
does is another round of 1-n hashings with some algorithm?

It kinda feels as if it might work for (A) but not for (B).

Or should one use --s2k-count 0 here (no salt no iterations) because
this is already done by e.g. Argon2id?


Thanks for any help,
Philippe.


More information about the cryptography mailing list