3

According to RFC 4880,

String-to-key (S2K) specifiers are used to convert passphrase strings into symmetric-key encryption/decryption keys. They are used in two places, currently: to encrypt the secret part of private keys in the private keyring, and to convert passphrases to encryption keys for symmetrically encrypted messages.

The latter works:

Screenshot

The former, for the secret part of private keys, does not:

gpg2 --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3 --s2k-count 65000000 --export-secret-keys | gpg2 --list-packets

Which shows a result that includes:

iter+salt S2K, **algo: 7**, **SHA1 protection**, **hash: 2**,
    **protect count: 13107200**.

So, it's a discreet, de facto downgrade to AES128 and GPU-friendly SHA-1 from what was expected. This problem was brought up here (about 42 months ago), and then lessened in urgency as a question after two years of inaction.

Gpg-agent has a default that limits the time that the KDF can take.

What can one do to get the s2k specifiers to fully work?

(Or at least get the same effect of significantly increasing the iteration count, which makes password cracking tough for the attacker)

  • 1
    Crossdupe https://security.stackexchange.com/a/149371/39571 which is probably a better place for it. (This is how-to-use-crypto-in-a-program not how-crypto-works.) – dave_thompson_085 Jun 18 '18 at 01:36
  • @ dave_thompson_085 Thank you! I need to search the other stackexchange sites before I post any question. That said, I wonder if anyone could give a clear answer. What can be done to get the s2k specifiers to work for private keys? –  Jun 21 '18 at 08:59
  • (1) hope the devs agree to the wishlist item and wait for them to do it (2) it's open source, do it yourself (but if you distribute, comply with GPL) (3) go back to 2.0 (or less?) and set at generation time (4) use something else instead of (or at least in addition to) gpg :-( – dave_thompson_085 Jun 22 '18 at 07:17
  • @ dave_thompson_085 Thanks again! Well, please fill me on point 4. What can I use that is better than GPG, or at least will complement it? I am very curious to know. –  Jun 22 '18 at 11:24
  • 1
    I'm sure there are other possibilites, but personally I would use BouncyCastle's 'bcpg' http://www.bouncycastle.org/latest_releases.html because Java is the fastest and easiest for me to code in. – dave_thompson_085 Jun 24 '18 at 06:40
  • 1
    @ dave_thompson_085 I need to turn my attention towards this and leave GPG2 in the dust. –  Jun 24 '18 at 12:47
  • I fully wasn't aware of this and it quite surprised me t.b.h. as there isn't even a warning or error that some option(s) specified (basically all s2k related ones) will not have any effect. in addition to what @dave_thompson_085 proposed (bouncy castle), i also got openpgp.js (v5.5.0) to generate keys where aes256 + sha512 + 65011712 rounds are used for the secret key package. Note that for sha512 being used, its needed to change a hardcoded assignment (defaulting to enums.hash.sha256) in class S2K. Also note that in the config-obj, one needs to specify an s2kIterationCountByte of 65011711. – antiplex Sep 12 '22 at 12:47

1 Answers1

0

Or at least get the same effect of significantly increasing the iteration count, which makes password cracking tough for the attacker

Not gpg but gpg-agent takes care of cleartext private keys. If a password or passphrase is provided during key creation, it encrypts the private key before storing it on disk.

Most of the time passwords and passphrases will be neither very weak nor very strong. To make all these not-so-great passwords and passphrases more resilient against brute-force attacks, gpg-agent doesn't use them right away, but uses a technique known as key stretching or s2k more specifically.

The s2k count is configurable and can be increased to improve the defenses against brute-forcing.

From the gpg-agent man page

--s2k-calibration milliseconds

Change the default calibration time to milliseconds. The given value is capped at 60 seconds; a value of 0 resets to the compiled-in default. This option is re-read on a SIGHUP (or gpgconf --reload gpg-agent) and the S2K count is then re-calibrated.

--s2k-count n

Specify the iteration count used to protect the passphrase. This option can be used to override the auto-calibration done by default. The auto-calibration computes a count which requires by default 100ms to mangle a given passphrase. See also --s2k-calibration.

--s2k-calibration was added in version 2.2.12 (which was released half a year after the question was asked). Usually people put these options in the configuration file, which is ~/.gnupg/gpg-agent.conf.

If key stretching is something you don't want to worry about, consider keeping the private key on an OpenPGP Smartcard (for example Nitrokey, Yubikey). This way you only need to remember two PIN codes which cannot be brute-forced.

peeed
  • 1