How to use OpenSSL to encrypt/decrypt files?
You should derive a Key and IV from the password using PKCS5_PBKDF2_HMAC . You should use the EVP_* functions to encrypt and decrypt. See EVP Symmetric Encryption and Decryption on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides both confidentiality and authenticity. See EVP Authenticated Encryption and Decryption on the OpenSSL wiki.
Don’t understand from your question why you want OpenSSL. A comment below shows GPG is better — also because of security. stackoverflow.com/a/31552829/952234 I vote down.
You may like to look at «keepout» so as to save all the encryption options used with the encrypted file. This is especially important now that ‘default’ options of openssl enc has changed, and will likely change in the future. Also sets a higher and randomised iteration count for the new -pbkdf2 option. antofthy.gitlab.io/software/#keepout
9 Answers 9
Security Warning: AES-256-CBC does not provide authenticated encryption and is vulnerable to padding oracle attacks. You should use something like age instead.
openssl aes-256-cbc -a -salt -pbkdf2 -in secrets.txt -out secrets.txt.enc
openssl aes-256-cbc -d -a -pbkdf2 -in secrets.txt.enc -out secrets.txt.new
Answer is likely not optimal (as of this writing) depending on OP’s use case. Specifically the parameters «-a» is likely not optimal and the answer does not explain its use. «-a» is typically used when the encrypted output is to be transmitted in ASCII/text form and has the effect of increasing output size compared binary form. The original poster does not specify output format and so I feel that at the very least this should be mentioned. See answer: stackoverflow.com/a/31552829/952234 which also includes a note on why you should use gpg instead of openssl for this task.
Do not use the above command since there is no key derivation. Read more here: openssl weak key derivation
@jonasl according to the latest man page, it states: “The default digest was changed from MD5 to SHA256 in Openssl 1.1.0.” Source: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Adding to the comment from @Kebman, you can add -md sha256 to your encode and decode command if you plan on using this file on another machine. That should cover you against OpenSSL version incompatibilities/differences
Using GPG (Better Alternative to OpenSSL)
Though you have specifically asked about OpenSSL (see «Using OpenSSL» below for OpenSSL solution) you might want to consider using GPG instead for the purpose of encryption based on this article OpenSSL vs GPG for encrypting off-site backups?
To use GPG to do the same you would use the following commands:
gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data
gpg --output un_encrypted.data --decrypt encrypted.data
Note: You will be prompted for a password when encrypting or decrypt. And use —no-symkey-cache flag for no cache.
Using OpenSSL (Short Answer)
You likely want to use gpg instead of openssl as mentioned above but to answer the question using openssl :
openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data
openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data
Note: You will be prompted for a password when encrypting or decrypt.
Using OpenSSL (Long Answer)
Your best source of information for openssl enc would probably be: https://www.openssl.org/docs/man1.1.1/man1/enc.html
Command line: openssl enc takes the following form:
openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]
Explanation of most useful parameters with regards to your question:
-e Encrypt the input data: this is the default. -d Decrypt the input data. -k Only use this if you want to pass the password as an argument. Usually you can leave this out and you will be prompted for a password. The password is used to derive the actual key which is used to encrypt your data. Using this parameter is typically not considered secure because your password appears in plain-text on the command line and will likely be recorded in bash history. -kfile Read the password from the first line of instead of from the command line as above. -a base64 process the data. This means that if encryption is taking place the data is base64 encoded after encryption. If decryption is set then the input data is base64 decoded before being decrypted. You likely DON'T need to use this. This will likely increase the file size for non-text data. Only use this if you need to send data in the form of text format via email etc. -salt To use a salt (randomly generated) when encrypting. You always want to use a salt while encrypting. This parameter is actually redundant because a salt is used whether you use this or not which is why it was not used in the "Short Answer" above! -K key The actual key to use: this must be represented as a string comprised only of hex digits. If only the key is specified, the IV must additionally be specified using the -iv option. When both a key and a password are specified, the key given with the -K option will be used and the IV generated from the password will be taken. It probably does not make much sense to specify both key and password. -iv IV The actual IV to use: this must be represented as a string comprised only of hex digits. When only the key is specified using the -K option, the IV must explicitly be defined. When a password is being specified using one of the other options, the IV is generated from this password. -md digest Use the specified digest to create the key from the passphrase. The default algorithm as of this writing is sha-256. But this has changed over time. It was md5 in the past. So you might want to specify this parameter every time to alleviate problems when moving your encrypted data from one system to another or when updating openssl to a newer version.
OpenSSL: простое шифрование с открытым ключом
Полно ситуаций когда нужно зашифровать определённый файл или папку. Например, если данные передаются по открытым каналам либо сохраняются на внешнем носителе. Многие (в том числе и я) используют truecrypt, однако основное предназначение этой программы — работа с зашифрованными разделами, поэтому она не очень хороша в этом случае.
Для подобных задач вполне подходит OpenSSL — надёжное кросплатформенное решение. OpenSSL поддерживает различные алгоритмы шифрования, плюс он по умолчанию установлен во многих операционных системах, а установка на остальные не составит труда.
Под хабракатом — основы использования симметричного и асимметричного шифрования в OpenSSL, а таке пара скриптов упрощающих асимметричное шифрование с одноразовым ключом.
Простейший способ защиты данных с помощью OpenSSL — симметричное шифрование. Следующие команды шифруют и расшифровывают файл documents.zip, используя алгоритм AES с длиной ключа 256 бит:
openssl enc -aes-256-cbc -salt -in documents.zip -out documents.enc
openssl enc -d -aes-256-cbc -in documents.enc -out documents.zip
Проблема этих команд может заключаться в том что они требуют ввода пароля. Есть ситуации когда это нежелательно. Например, автоматическое резервное копирование/шифрование данных по расписанию, либо если данные шифруются одним человеком а расшифровываются другим.
Как раз для таких случаев было придумано шифрование с открытым ключом. В общем случае вам понадобится создать открытый и закрытый ключи. Первая команда сгенерирует закрытый ключ private.pem, вторая создаст открытый ключ public.pem:
openssl genrsa -out private.pem -aes256 2048
openssl rsa -in private.pem -pubout -out public.pem
В результате вы получаете пару RSA ключей длиной 2048 бит. К сожалению, в системе RSA размер шифруемых данных ограничен размером ключа, поэтому зашифровать более 2Кб данных не получится. Есть способ обойти это — информация сначала шифруется симметричным алгоритмом (подобно использованному выше) с использованием одноразового ключа. Затем этот одноразовый ключ шифруется публичным ключом. При расшифровке одноразовый ключ расшифровывается закрытым. Подробнее об этом уже было очень хорошо написано в статье на Хабре.
Автоматизировать шифрование поможет следующий скрипт, на выходе которого вы получите одноразовый ключ и данные (encrypt.sh) в зашифрованном виде:
FILENAME=»$1″
PUBLICKEY=»$2″
SESSIONKEY=»$3″
RESULT=»$4″
# Generate the random symmetric-key
PASSIZE=30
if [ -c /dev/urandom ] ; then
KEY=`head -c 30 /dev/urandom | openssl enc -base64`
else
KEY=`openssl rand -base64 30`
fi
export KEY
# Encrypt the symmetric key using the public key
openssl rsautl -encrypt -inkey «$PUBLICKEY» -out «$SESSIONKEY» -pubin $KEY
EOF
# Encrypt the file
openssl enc -aes-256-cbc -pass env:KEY -in «$FILENAME» -out «$RESULT»
Следующая команда использует открытый ключ public.pem чтобы зашифровать файл documents.zip. Она сгенерирует зашифрованный одноразовый ключ session.key и зашифрованные данные documents.enc:
./encrypt.sh documents.zip public.pem session.key documents.enc
Скрипт для дешифрования (decrypt.sh):
PRIVATEKEY=»$1″
SESSIONKEY=»$2″
ENCRYPTED=»$3″
DECRYPTED=»$4″
# Decrypt the symmetric key using the private key
KEY=` openssl rsautl -decrypt -inkey «$PRIVATEKEY» -in «$SESSIONKEY» `
export KEY
# Decrypt the file
openssl enc -aes-256-cbc -d -pass env:KEY -in «$ENCRYPTED» -out «$DECRYPTED»
Команда для дешифрования использует закрытый ключ private.pem и одноразовый ключ session.key чтобы расшифровать файл documents.enc. Она сгенерирует файл documents.zip:
./decrypt.sh private.pem session.key documents.enc documents.zip
Как видите, шифрование с открытым ключом может быть почти таким же простым как и симметричное. Но есть ещё более простой путь. На написание этого поста меня побудил блог SbF₅. Его автор (несомненно более искушённый в bash чем я) написал скрипт, который архивирует папку, шифрует её открытым ключом и генерирует другой скрипт, содержащий в себе всё необходимое: одноразовый ключ, данные и собственно команды для расшифровывания. Кроме того, скрипт может сгенерировать для вас пару RSA ключей:
./encrypt-file.sh -keys public.pem private.pem
./encrypt-file.sh folder public.pem > decrypt-folder.sh
chmod +x decrypt-folder.sh
./decrypt-folder.sh private.pem > folder.tar
В этом примере мы сначала сгенерировали пару ключей. После этого папка folder была зашифрована в скрипт decrypt-folder.sh а затем расшифрована в архив folder.tar. Возможный минус этого способа — то что данные в decrypt-folder.sh хранятся в формате BASE64, а следовательно их размер увеличивается.
Вот, собственно, то, чем я хотел поделиться. Если у кого-то есть замечания или вопросы — пишите в комментарии, постараюсь ответить.
UPD Перенесено в блог Информационная безопасность.
How can I encrypt / decrypt AES-256 CBC with OpenSSL?
I just installed Linux (Ubuntu) for the first time and downloaded package OpenSSL as well. Opened command line too and tried some commands but none of them worked. So what I have is initial vector: 5a04ec902686fb05a6b7a338b6e07760 , also have ciphertext: 14c4e6965fc2ed2cd358754494aceffa and the corresponding plaintext: We’re blown. Run Now I imagine there must be a command where you enter the initial vector and the plaintext and as a result you should get the ciphertext. Another possibility: Enter initial vector and ciphertext, get the plaintext. But how can I do this in the command line? I’ve already tried the command:
openssl aes-256-cbc -e -nosalt -a -in input.txt -out output.txt -k key -iv ivkey
about input.txt : I have created this file on my Desktop and wrote the plaintext in it. About output.txt , I created it as well and put it on Desktop, it’s empty. After using this command, nothing happens! Is there any other command that could help me? I have also tried to find some helpful tool on the internet but nothing seemed to work! : /
You also don’t want -a if you want a hex output. Pipe it to xxd instead. Since the plaintext and ciphertext are both exactly 16 bytes you’ll also want -nopad .
Then it seems it doesn’t realize that you are specifying the raw keys. Remember to use -K with the hex key and -iv with the hex IV. That will allow it to take that directly rather than prompting you for a password. When it’s asking you for a password, it is looking for ASCII which it will hash with SHA-256 (on newer builds) or MD5 (on older builds) before using directly as the key.
You have to use the key used to encrypt it. If you don’t know the key you can’t decrypt it. that’s how cryptography works.
You’re still missing the -K . And what’s the xxd in there for? You’d want to use xxd to view the file after decryption.