7

Suppose I use GnuPG to symmetrically encrypt a file like so:

gpg --no-options -c --cipher-algo AES256 --no-random-seed-file -o my.out my.file

I then provide a passphrase when prompted.

  • What steps does the software actually take to get from the passphrase I provide as a user, to the actual 256-bit AES key which is used to secure the data?
  • What data relating to or derived from the passphrase is stored in the output ciphertext file?
  • What of the above is guaranteed by the standard, and what is implementation-defined?
F1Linux
  • 273
  • 7
  • 13
user
  • 273
  • 3
  • 15

1 Answers1

6

GPG implements the OpenPGP standard RFC 4880, so it implements the String-to-Key Specifiers.

3.7. String-to-Key (S2K) Specifiers

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.

3.7.1. String-to-Key (S2K) Specifier Types

There are three types of S2K specifiers currently supported, and
some reserved values:

   ID          S2K Type
   --          --------
   0           Simple S2K
   1           Salted S2K
   2           Reserved value
   3           Iterated and Salted S2K
   100 to 110  Private/Experimental S2K

I wrote my own implementation of OpenPGP a while back, if you dont want to search through the GPG source code. If I remember correctly, while decrypting test data I generated with GPG, I found that by default, GPG uses Iterated and Salted S2K (S2K3).

std::string S2K3::run(std::string pass, unsigned int sym_len){
    // get string to hash
    std::string to_hash = "";
    while (to_hash.size() < coded_count(count)){// coded count is count of bytes, not interations
        to_hash += salt + pass;
    }
    to_hash = to_hash.substr(0, coded_count(count));
    // hash string
    std::string out = "";
    unsigned int context = 0;
    while (out.size() < sym_len){
        out += use_hash(hash, std::string(context++, 0) + to_hash);
    }
    return out.substr(0, sym_len);
}

As for your second and third questions, I don't know. I would hope that no information of the password is stored in the file. I have tried to read the GPG source code, but failed doing so. It is very large and complex.

calccrypto
  • 536
  • 1
  • 9
  • 26