95

I want to encrypt a file using AES-256. How can I do that quickly and easily, and how can I - or someone else -decrypt it again?

7 Answers 7

106

Unfortunately, there is no easy solution to securing your stuff. Think about your use-case, maybe something other than plain AES is better suited.


If you want very simple platform independent encryption, you can use openssl.

Please note: You can use this to hide birthday-gift-ideas.txt from your roommate, but don't expect it to be secure against a determined attacker!

  1. As was pointed out in the comments, this method uses a naive key derivation function, so your password needs to be superlatively good in order for you to have a chance of being secure.
  2. Additionally, this method doesn't authenticate the ciphertext, which means an attacker can modify or corrupt the contents without you noticing.
  3. For many types of security, encryption is simply not enough (e.g. you can't just use encryption to communicate securely)

If you still want to use openssl:

  • Encryption:

    openssl aes-256-cbc -in attack-plan.txt -out message.enc

  • Decryption:

    openssl aes-256-cbc -d -in message.enc -out plain-text.txt

You can get openssl to base64-encode the message by using the -a switch on both encryption and decryption. This way, you can paste the ciphertext in an email message, for example. It'll look like this:

stefano:~$ openssl aes-256-cbc -in attack-plan.txt -a
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
U2FsdGVkX192dXI7yHGs/4Ed+xEC3ejXFINKO6Hufnc=

Note that you have a choice of ciphers and modes of operation. For normal use, I recommend aes 256 in CBC mode. These are the ciphers modes you have available (only counting AES):

aes-128-cbc ← this is okay
aes-128-ecb
aes-192-cbc
aes-192-ecb
aes-256-cbc ← this is recommended
aes-256-ecb

See also:

Please note:

OpenSSL will ask you for a password. This is not an encryption key, it is not limited to 32 bytes! If you're going to transfer files with someone else, your shared secret should be very strong. You can use this site to get a sense of how good your password is:

Warning: I have checked that these sites don't send your password to the server, but that can change at any time. Use these sites with dev tools / inspector and check if they send anything before typing in your strong password.

9
  • 10
    openssl aes-256-cbc is shorter than openssl enc -aes-256-cbc and works too. The manual page for this is available by running man enc. Never use ecb for data that should not be tempered with, always use cbc. -salt is redundant since it's default. If you omit -out filename the output will be written to standard output which is useful if you just need to analyze data, but not write it to disk. THe next command shows the line cound for the plaintext: openssl aes-256-cbc -d -in filename | wc -l. (another use, reading a file: openssl aes-256-cbc -d -in filename | less)
    – Lekensteyn
    Sep 9, 2011 at 16:37
  • 1
    I use almost exactly this in a script : /usr/bin/openssl enc -aes-256-cbc -a -salt -in $1 -out ${1}.enc with the reverse as you would expect.
    – belacqua
    Sep 11, 2011 at 0:29
  • 1
    There is no reason to prefer AES 256 to AES 128. @Lekensteyn Never use ECB for confidential data either — basically ECB should never be used (for experts only: ECB should never be used except in some very specific cases). More generally, the openssl command line tool is mostly a proof-of-concept for testing the OpenSSL library. The right answer to this question is either GPG or some archiver such as 7z. Apr 18, 2014 at 12:00
  • 1
    I would like to add that openssl enc is actually not that secure if you have a weak password. I previously recommended certain usage of openssl enc, but now suggest to use gpg instead because it uses a KDF in a better way. See this answer.
    – Lekensteyn
    Apr 27, 2014 at 22:16
  • 2
    -1 For recommending low-level OpenSSL use. It does not provide any HMAC functionality and as @Lekensteyn points out, it lacks proper KDF.
    – gertvdijk
    Dec 9, 2014 at 13:00
48

I like to use the gpg command:

Encrypt:

gpg --cipher-algo AES256 --symmetric filename.tar.gz

Shorthand:

gpg --cipher-algo AES256 -c filename.tar.gz

This will ask for a passphrase.

Decrypt:

gpg --output filename.tar.gz --decrypt filename.tar.gz.gpg

Shorthand:

gpg -o filename.tar.gz -d filename.tar.gz.gpg

You can also add cipher-algo AES256 to ~/.gnupg/gpg.conf to make AES256 the default. (According to manpage it is CAST5)

5
  • You can also use AES (meaning AES-128). AES-128 is slightly faster and is not less secure. Apr 18, 2014 at 12:01
  • 2
    +1. Also note that GnuPG also provides message authentication (HMAC) for you when using AES (which OpenSSL lacks being the most upvoted answer at the time of writing). Background info: superuser.com/a/633716/157409
    – gertvdijk
    Dec 9, 2014 at 13:01
  • 1
    It looks like the first command stores your password somewhere (in 20.04), so that when you decrypt the file, it doesn't even ask you for a password. This is unexpected. And I couldn't even stop gpg from doing that with --no-keyring.
    – MWB
    Jun 14, 2021 at 3:16
  • @MWB This surprised me, too. You can prevent this either with the --no-symkey-cache flag, or by adding the line no-symkey-cache to your ~/.gnupg/gpg.conf file. If the password was cached before updating the conf file, you can clear it by reloading the agent: echo RELOADAGENT | gpg-connect-agent
    – wilkystyle
    Feb 10, 2022 at 20:55
  • Turns out that if you run this at scale (like decrypting millions of files), there may be some secure memory limits that will cause some of your files to not be decrypted.
    – Alper
    Feb 3, 2023 at 10:58
21

7z (when the password option is used) uses a 256bit AES encryption (with SHA256 key stretching).

Install it (p7zip-full), right click on a file or directory you want to encrypt, and choose Compress, .7z and Other options /Password.

enter image description here

For decryption, right click on the .7z file and choose Extract here.

1
  • 1
    How do you launch the GUI for 7z?
    – m0skit0
    Mar 17, 2019 at 13:30
6

aescrypt

The linked website contains an open-source 256-bit aes encrypt/decrypt tool and is multiplatform - MacOs, Windows, Linux and others through Java.

Encrypt: aescrypt -e <file>

Decrypt: aescrypt -d <file>

You could backup and encrypt your home folder using the syntax:

tar -cvf - /home/<home_folder> | aescrypt -e -p <password_message> - > backup.tar.aes

ubuntu installation

Download and extract the source

make
sudo make install

other platforms

Download the binaries or source-code from the website.

0
4

A lot of the suggestions I would have made have already been put forth in this thread. Basically, openssl is really the easiest way to go about encrypting a file or script. However, I would caution against using AES-256 just because it is not available in all versions of openssl on some platforms. Most newer OSes...i.e. Linux have it. But others such as AIX 5.3 do not (i think HP-UX as well). If you intend to use your file or script across different platforms, I strongly recommend using AES-128 because this is available everywhere.

How can you "quickly and easily" encrypt a file using AES-128?

A site like www.ShellScrypt.com uses openssl AES-128 quite intensely to encrypt shell scripts and then makes the encrypted copies of the scripts executable. All you have to do is paste the script to the site, and a zip file will be generated for you. That zip file will contain the encrypted (and executable if it is a script) version of your file. This allows you to "easily" and "conveniently" encrypt a file/script without having to satisfy any package or module requirement on every system you intend to use the script on or run several complex and confusing incantations of openssl commands.

Shown below is a basic encrypt / decrypt openssl command that uses AES-128:

test@test-VirtualBox:~$ 
test@test-VirtualBox:~$ echo precious-content | openssl aes-128-cbc -a -salt -k mypassword
U2FsdGVkX1+K6tvItr9eEI4yC4nZPK8b6o4fc0DR/Vzh7HqpE96se8Fu/BhM314z
test@test-VirtualBox:~$
test@test-VirtualBox:~$ echo U2FsdGVkX1+K6tvItr9eEI4yC4nZPK8b6o4fc0DR/Vzh7HqpE96se8Fu/BhM314z | openssl aes-128-cbc -a -d -salt -k mypassword
precious-content
test@test-VirtualBox:~$ 
test@test-VirtualBox:~$
1
  • 2
    Just leaving a comment to give a heads-up that “shellscrypt.com” is down and out (aka: the site is gone).
    – e-sushi
    Oct 19, 2017 at 18:38
4

Mentioning recent option added to openssl since OpenSSL 1.1.0. Building on stefano-palazzo answer:

openssl enc -aes-256-cbc -a -e -in input.tar.gz -out oupput.enc -pbkdf2 -iter 1000000 -md sha512

It uses a Key Derivation Function, lacking it would make bruteforcing password a lot easier.
For decrypting use:

openssl enc -aes-256-cbc -a -d -in output.tar.xz.enc -out output.tar.xz -pbkdf2 -iter 1000000 -md sha512

Explaining arguments:
enc stands for encryption
-aes-256-cbc is a good way of using a AES cipher
-a base64 your data after encryption or before decryption
-d decrypt
-e encrypt
-in input file
-out output file
-pbkdf2 streches the key to it would be hard to break Key Derivation Function
-iter iterations to strech the key, more means more security and adequate number is described here
-md sha512 is replacing the hash function of PBKDF2 with SHA512 which is more secure than the default SHA256
-salt not mentioned in the command because it is set by default and is a very good way to increase security, why is that is described here

3

Adding to Stefano Palazzo's answer, I created a little bash function that works similarly to the base64 command.

It will aes256 encrypt a file, and then base64 encode it. When doing the reverse, it will base64 decode, decrypt, and then spit out the original plaintext.

aes256() {
  decodeMe=""
  isPipe="$([ ! -t 0 ] && echo "true" || echo "false")"

  if [ "$1" = '-d' ] || [ "$1" = '--decode' ]; then
    decodeMe="-d"
    shift
  fi

  if [ "$isPipe" = "true" ]; then
    read input
    printf '%s\n' "$input" | openssl aes-256-cbc -a $decodeMe
    exitCode="$?"
  else
    openssl aes-256-cbc -a $decodeMe -in "$*"
    exitCode="$?"
  fi

  unset isPipe decodeMe input
  return "$exitCode"
}

Usage:

echo "my string" | aes256
# enter aes-256-cbc encryption password
# Returns: U2FsdGVkX1++e/BhBGlNOzNvarqq7zI13S/hbiKVzXQ=

echo "U2FsdGVkX1++e/BhBGlNOzNvarqq7zI13S/hbiKVzXQ=" | aes256 -d
# enter aes-256-cbc decryption password
# Returns: my string

aes256 file.plain > file.crypt
# enter aes-256-cbc encryption password

aes256 -d file.crypt
# enter aes-256-cbc decryption password
# Spits out original unencrypted file.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .