Skip to content

dual, double, cascaded, chained symmetric encryption based on either GPG or OpenSSL

License

Notifications You must be signed in to change notification settings

8go/gpg-openssl-encrypt-twice-symmetrically

Repository files navigation

gpg-openssl-encrypt-twice-symmetrically

TLDR; dual/double/cascaded/chained symmetric encryption based on either GPG or OpenSSL

The gpg-openssl-encrypt-twice-symmetrically repository contains a set of bash scripts that allow you to encrypt data (such as a file) twice with two different ciphers in a symmetric way, i.e. with two passwords. The goal was to provide a set of small scripts that are a good solution to perform symmetric encryption twice with a result that is safe, secure, and viable for a long time (10+ years). Encrypting something twice symmetrically is also known under the terms of dual, double, cascaded, multiple, or chained symmetric encryption.

Two pairs of scripts are provided:

  • a GPG variant: a pair of scripts based on gpg
  • an OpenSSL variant: a pair of scripts based on openssl
  • each variant has 2 scripts: one to encrypt and one to decrypt
    • Even though there are 2 scripts, the encrypt script has the logic for both, encryption and decryption so that all the logic is in a single file. This is done for simplicity. The decrypt script is just a dummy calling the encrypt script with an argument.

Usage

gpg-encrypt-twice-symmetrically.sh [--help] [--encrypt|--decrypt] files
openssl-encrypt-twice-symmetrically.sh [--help] [--encrypt|--decrypt] files

gpg-decrypt-twice-symmetrically.sh [--help] files # dummy script, calls gpg-encrypt-twice-symmetrically.sh
openssl-decrypt-twice-symmetrically.sh [--help] files # dummy script, calls openssl-encrypt-twice-symmetrically.sh

Examples:

gpg-encrypt-twice-symmetrically.sh --help # print help
gpg-encrypt-twice-symmetrically.sh --encrypt myhealthcarerecord.pdf # encrypts one file
# produces file myhealthcarerecord.pdf.enc as output and some additional outputs (meta-data, QR codes, etc.)
gpg-encrypt-twice-symmetrically.sh myhealthcarerecord.pdf # encrypts one file, --encrypt is used by default
# produces file myhealthcarerecord.pdf.enc as output and some additional outputs (meta-data, QR codes, etc.)
gpg-encrypt-twice-symmetrically.sh --decrypt myhealthcarerecord.pdf.enc # decrypts one file
# produces file myhealthcarerecord.pdf as output
gpg-decrypt-twice-symmetrically.sh myhealthcarerecord.pdf.enc # decrypts one file, same as previous command
gpg-encrypt-twice-symmetrically.sh myhealthcarerecord.pdf lawyerbill.doc # encrypts two files
gpg-encrypt-twice-symmetrically.sh # encrypts input from stdio (e.g. keyboard or pipe)

If you replace gpg with openssl you get the examples for the openssl variant:

openssl-encrypt-twice-symmetrically.sh --help # print help
openssl-encrypt-twice-symmetrically.sh myhealthcarerecord.pdf # encrypts one file
openssl-encrypt-twice-symmetrically.sh --decrypt myhealthcarerecord.pdf.enc # decrypts one file
...

You cannot mix-and-match. If you encrypt with the gpg script, you must decrypt with the gpg script. If you encrypt with the openssl script, you must decrypt with the openssl script.

Differences between the GPG and OpenSLL variants

  • different ciphers: Chacha20 vs TwoFish
    • gpg variant uses first AES256 and then TwoFish
    • openssl variant uses first Chacha20 and then AES256
  • different amount of iterations of password hashing
    • the maximum number of hash iterations is low in GPG
    • the maximum number of hash iterations is nearly unlimited in OpenSSL
    • with openssl variant it is easier to slow attacker down, one can pre-hash the password even for an hour if desired
  • number of iterations of password hashing recall
    • gpg variant stores it in the encrypted file, so not needed on decryption
    • with openssl variant you need to know/remember this number in order to decrypt! This number is hardcoded in the script.
  • resulting file sizes
    • gpg variant output file sizes are slightly larger
    • for a plaintext of 347 bytes, openssl variant produced an output of 520 bytes, gpg variant an output of 752 bytes

Similarities between the GPG and OpenSLL variants

  • both use symmetric encryption
  • both use symmetric encryption twice
  • both use AES256 as one of the ciphers they use
  • both use a digest

Miscellaneous Observations

  • encrypt and decrypt operations consume about the same time and CPU, memory resources
    • if encryption took N millsec, then decryption will also roughly take N millisec
  • the sizes of the encrypted output files is roughly the same in both variants
    • no variant is more space efficient than the other

Warning

  • Remember: both variants are ONLY secure if the two passphrases are difficult,
    • using easy passphrases will lead to easy-to-break results
    • using the same password for both ciphers makes no sense, use simple encryption in that case, it is meaningless to encrypt twice if you use the same passphrase
  • It is recommended that you also keep a copy of the scripts that you used together with your encrypted files.
  • Open source. GPL3 license. Use as you like. No warranty. No claims.
  • Not liable. Not responsible for losses or damages.

PRs welcome. If you find it useful, give it a ⭐ in Github.




Comments on Symmetric Encryption, State-of-the-art in 2020

Research from fall 2020

Primary objective of this research was to find a good solution to dual/double/cascade/multiple/chained symmetric encryption that is safe, secure, and viable for a long time (10 years).

Goals

  • symmetric: for ease
  • dual: to not depend on one cipher/algorithm
  • the two ciphers should be as orthogonal, as different, as possible
  • simplicity
  • should use existing, established, respected high level tools
  • should not use a library to avoid coding, and in turn to avoid making mistakes
  • quantum resistance

Preliminary Conclusions

  • Option A: openssl with ChaCha20 first, AES-256-CBC second, with message digest
    • with salt, and password hashing of 100,000,000 rounds, etc.
    • implementation of openssl solution written in Bash, 400 LOC
    • example file sizes:
         520 bytes ::  plaintext-openssl.enc --> output
         471 bytes ::  plaintext-openssl.inf --> meta data
         347 bytes ::  plaintext-openssl     --> input, sentence with 51 words
        3224 bytes ::  plaintext-openssl.png --> QR code with 970x970 pixels
         152 bytes ::  plaintext-openssl.sha --> hash
      241562 bytes ::  plaintext-openssl.svg --> QR code with 970x970 pixels
      
  • Option B: gpg with AES-256 first, TwoFish second, with message digest
    • with salt, and password hashing of 65,000,000 rounds, etc.
    • implementation of openssl solution written in Bash, 400 LOC
    • example file sizes:
         752 bytes ::  plaintext-gpg.enc --> output
        2125 bytes ::  plaintext-gpg.inf --> meta data
         347 bytes ::  plaintext-gpg     --> input, sentence with 51 words
        4354 bytes ::  plaintext-gpg.png --> QR code with 1130x1130 pixels
         144 bytes ::  plaintext-gpg.sha --> hash
      335181 bytes ::  plaintext-gpg.svg --> QR code with 1130x1130 pixels
      

Terminology

  • Some use the term secret key encryption instead of symmetric encryption.
  • Some use the term public key encryption instead of asymmetric encryption.
  • These terms are used for encrypting twice: dual, double, cascaded, multiple, or chained symmetric encryption_

Existing implementations

Interesting reading

AES256

AES512

Chacha20

Twofish

Serpent

GPG2

  • GPG with TwoFish and AES256 and SHA512 digest (AES first, TwoFish second)
  • Options, arguments:
       gpg --symmetric \
       --cipher-algo aes256 \
       --digest-algo sha256 \
       --cert-digest-algo sha256 \
       --compress-algo none -z 0 \
       --quiet --no-greeting \
       --no-use-agent "$@" \
       --s2k-mode 3 \
       --s2k-digest-algo sha512 \
       --s2k-count 1000000
    

LibreSSL

Age

  • age does not seem widely used, not established? More like an up-and-coming tool. Will age be around in 10 years?
  • no options on purpose to keep it simple, so no fine-tuning possible
  • to be determined: does age use library libsodium or NaCl (https://en.wikipedia.org/wiki/NaCl_(software))? The definite answer is to look at their source code and see what libs they import.
  • libsodium / NaCl offers BOTH: AES and ChaCha20 (as well as authentication, i.e. the Poly1305 part), https://nacl.cr.yp.to
  • Rust implementation rage

Scrypt

Keybase.io, VeraCrypt

  • VeraCrypt: only does hard-disk encryption (like LUKS), not file encryption
  • keybase.io: They ONLY use asymmetric encryption. No symmetric encryption available. It uses libsodium, or NaCl.

Misc Thoughts

  • using a random number for iterations could be even more secure but what if you lose the meta data (the .inf file)?
  • using QR code for obfuscation
  • If one ever wants to program encryption stuff, these are good high-level packages:
  • To delay the brute-force attacker, if gpg is used, it could be considered to pre-hash the password before calling gpg. This makes the low maximum iteration count in PGP irrelevant, and if scrypt is used it adds an additional challenge to the attacker as he now also needs to deal with a second hashing algorithm and with high RAM requirements for his attack hardware.