I'm using a script to pack and encrypt archives in order to backup them in cloud storage.
It generates shell commands like this:
cd /vault/backup/pictures; tar cf - vacation-201309 | xz -3 | gpg --symmetric --cipher-algo TWOFISH --digest-algo SHA512 --no-secmem-warning --yes --batch --passphrase-file /vault/keys/back_keyfile -o /vault/backup/upload/vacation-201309.tar.xz.gpg
TWOFISH is a 256-bit cipher which means, that it can only use a keyfile not bigger than,
openssl rand -base64 256:
3zXeZC/XWC1h1lxre88gzkhCZqk6tV7YKCg9HiKDLrooEDYkvwYXQ5LMBLSFdpYr
c2KAP10aq6pfEi4YeL7llQXfd47qXsEDi8nOpBpPRALxv2NYE4qjZC3sTPe+d1ue
cbFM18BmxHN0094YotLBD+6cQIfZyU8GVLLHx8iH2jf48+7QuXigqWW1oT33BPbQ
zrlND50ZFeGNYo7woIRpSvt8KeBm8t75jVEqXIzA2Zei0r9Xsx0mu828t0wZ6mGL
hkj4B5M56eJzFUCFG207Mf/bXvV5X7Pz6W72Y8nhjAtkumdAsEb0Vc0iIHJ64mfH
XWEfs/1T3n2F8/kxASIvPQ==
At least that's how I understand it.
My question is, how would GPG behave, if I pass a bigger key file to it like
openssl rand -base64 512:
P0MzGpZItSu6fKObtJvAx1fLRxPBK/pOIjR9Yv+mCrHLlit7ksHOjif6ln32lXl3
8g/zxdQc39kanAproaOzZ1ulebxbfK1Bi6/OfwhdP1HF61nWBZb03TDtdNNXEDFW
9lAN6kHUUctpY9PhFCv2AmoKSKzv1HsAGkrhqslO4E+3sIlGgVLg69qKHE9yQJSX
s5xhXKTcAcaVZ++HwuTTvIduf3sc2J+BEDzpqrAwES2hV5gFwnFFA6G0md31VwEI
9wf22p07qbOrRryV/0WZUNZfOuZ5g/JgrqhRgq53lK0VHvyRkNjMlx7BW4n3Y/0y
5Lgve8Q89Cx5jwbxPcBnXW5h4SWLFa8bSLrGrn/eDH+F1mA5BbU+3IrBdLgivz0u
Unr+jLD3FbBOv/8jRAyp/iOwMmOw9welTu/mcEEa20gyupeJXxAZaVrNfWdWVORi
PdjW5vR9Rn/NLh6fV46+E39dgTn4TBp/v9h+LZpiVK3nNkry+as9vH73o+nFIe8Q
H/UkchDqmIBLntKc9rBZQrkx8NOzruoWGJoFE/Wb23AHN7RNyYgVgvZTy5QWhILz
CW/mzwMQYAuLbFfnY4cgDs9zLMo4OqFGUmbgbnXO9KbYgsplU2aps9JoOjyWCchm
uWYRNAGWrgdfl8vIaxMz1WUwWJFDxyNrANPRiPFQTUg=
Will it just take the first 256 characters and ignore the rest?
You are using the random as input as a passphrase. Only the first line is used. So you are not generating the key at all, the key is generated using the S2K algorithms, using just the first line.
Note that a 256 bit key does not consist of 256 "characters" or bytes.
Related
Im trying to decrypt a text, which was encrypted with AES-256-ECB with the given key. To decrypt, Im using the same version of the openssl which was used for encryption (OpenSSL 1.1.1d 10 Sep 2019).
String to decrypt: VAWawVAWawxiyH20dI+t5NPAY9w== (inside file.txt)
Key: 461a966faef244e4808d6b2b8e928d01 (inside key.txt)
I tried those commands:
cat file.txt | base64 -d > file2.txt
openssl enc -AES-256-ECB -d -in file2.txt -out answer.txt --kfile key.txt
And im getting: bad magic number. Whats the problem?
openssl enc will normally use a password to derive a key. So it is the derived key that is used to decrypt the file. The derivation process requires a "salt", and openssl enc during encryption stores that salt at the beginning of the file along with a "magic number" to identify it. If the magic number is missing (usually because the file wasn't encrypted by openssl enc or because the password based key derivation derivation method wasn't used) then you get this error.
The -kfile option tells OpenSSL to read the password from a file and then derive the key from it. Probably want you intended was to not use password derivation at all, but to use the explicit key. In which case you need to use the -K option and supply the key on the command line using hex.
I'm learning cryptography, and I want to use the OpenSSL command line to generate a triple DES key coded in base64 and save the resulting key to a text file, then I want to encrypt a text message using this key file.
I used the standard command "rand" to generate a random value of size 24 bytes coded in base64 and saved it as a key in a text file, but I don't know how to use this file to encrypt a text message using the command "enc", and I'm wondering if there is a better way to generate a triple DES key using OpenSSL command line.
This isn't a programming or development question, and not really ontopic for SO. It would fit better on security.SX or maybe superuser.
If this were (or is) anything oher than a throwaway test, saving a key in clear in a file is probably going to be insecure. That part really belongs on security.SX.
Technically a triple-DES key (like a single-DES key in the years before it was obsolete) should have the low bit of each octet (on modern systems, byte) set for odd parity. In the '70s when DES was developed and usually implemented in specialized hardware using discrete transistors, this was a very important feature. For the last few decades, and especially for software, these parity bits are usually ignored. For OpenSSL in particular, libcrypto ignores them by default (although there is an option to set or check) and commandline enc uses the libcrypto default.
Commandine enc defaults to password-based encryption which derives the key from a supplied password, but can take the actual key with -K (uppercase) IN HEX; see the man page.
On Unix this would make it easy if you use rand -hex instead:
openssl rand -hex 24 >key.hex
openssl enc -des-ede3-cbc -K $(cat key.hex) -iv 0123456789ABCDEF -in X -out Y
# see below
On Windows this is also manageable but not as easy; you need something like
openssl rand -hex 24 >key.hex
for /f %t in ('type key.hex') do set k=%t
rem double the % if used in a batch file
openssl enc -des-ede3-cbc -K %k% -iv 0123456789ABCDEF -in X -out Y
rem ditto
If you insist on base64, you'll need a helper program on Unix
openssl rand -base64 24 >key.b64
K=$( openssl base64 -d <key.b64 | xxd -p )
openssl enc -des-ede3-cbc -K $K ... # as above
and I don't think it can be done on Windows at all.
Note the IV should be different for each encryption, not hardcoded as in my example, and for CBC in particular it should also be unpredictable by an adversary; this is often most easily done by making it random. Although if it's not CBC mode only loses security to an active attacker while if it repeats at all other modes like CTR and OFB lose security even to a passive attacker. This part belongs on security.SX or crypto.SX where there are already dozens if not hundreds of Qs about it.
I am trying to encrypt using RC4 using openssl. I can match results with online cipher tools only with key as hex but not as plaintext.
Using password option with plaintext - DOES NOT MATCH.
# echo -ne "stackoverflow" | openssl rc4 -pass pass:"rc4cipher" -nopad -nosalt | xxd -p
Result : 8189898ec30bd96a81bca0e293
Getting the symmetric key for the password
#echo -ne "stackoverflow" | openssl rc4 -pass pass:"rc4cipher" -nopad -nosalt -p
key=1E8B649064CC6657312EE7346ED410A4
With hexa key for the above password (-k option) - MATCHES.
echo -ne "stackoverflow" | openssl rc4 -K "1E8B649064CC6657312EE7346ED410A4" -nopad -nosalt | xxd -p
Result :8189898ec30bd96a81bca0e293
I can match my result with online tools by using key as hex but not as plain text.
Can someone help please me with the option to use with openssl ?
Thanks,
Ak
Keys should consist of random binary data. They should not consist of text. If you need to perform password based encryption you need to use a password hash or, more precisely, a Password Based Key Derivation Function to turn the password into a key. Common PBKDF's are bcrypt, scrypt, PBKDF2 and Argon2.
And this is what OpenSSL (command line) does underneath: it uses a weak, OpenSSL proprietary algorithm called EVP_BytesToKey. This is basically only compatible with OpenSSL implementations or compatibility libs.
Most online tools (which you should never use to validate any implementation in the end) simply convert the text to binary using character-encoding such as UTF-8, Windows-1252 or any other - usually unspecified - encoding. This is not secure; it's as braindead as most click-bait encryption tools found online.
I am doing a project with encrypting
video and I have a few questions for the procedure.
I used a command to transcode mp4 to HLS with a ts segment duration of ~10 seconds.
First, I need to encrypt those videos with a key from database. However,
I have no idea for the encryption whether working with ffmpeg or not.
Second, if the encryption can work without ffmpeg, so what should I do? I have searched in google which includes something like openssl / aes but
there is no a detailed step for me to follow, even the ffmpeg link:
http://www.ffmpeg.org/ffmpeg-all.html#srtp
Could anyone give me a hand, teaching me how to encrypt a video? Thanks to you.
Yes, you can do it with ffmpeg. You need to write the key from the database to a file, let's say video.key.
You need a second file, let's name it key_info which is the key info file. It has the following format:
key URI
key file path
IV (optional)
Eg:
http://example.com/video.key
video.key
You tell ffmpeg to use it to encrypt your segments with the hls_key_info argument:
ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 10 -hls_key_info_file key_info playlist.m3u8
This will encrypt your segments with AES-128 in CBC mode and add the relevant tags to your playlist:
#EXT-X-KEY:METHOD=AES-128,URI="http://example.com/video.key"
You can also manually encrypt the segments if you want with openssl. Here's an example script, where each IV is equal to the segment index:
#!/bin/bash
ts_dir=/path/to/ts/
key_file=video.key
openssl rand 16 > $key_file
enc_key=$(hexdump -v -e '16/1 "%02x"' $key_file)
pushd $ts_dir
ts_cnt=$(ls *.ts | wc -l)
((ts_cnt--))
i=0
for i in $(seq -f "%01g" 0 $ts_cnt); do
iv=$(printf '%032x' $i)
ts_file=segment-$i.ts
echo [$i] $ts_file
openssl aes-128-cbc -e -in $ts_file -out encrypted_${ts_file} -nosalt -iv $iv -K $enc_key
done
popd
I want to encrypt and decrypt one file using one password.
How can I use OpenSSL to do that?
Security Warning: AES-256-CBC does not provide authenticated encryption and is vulnerable to padding oracle attacks. You should use something like age instead.
Encrypt:
openssl aes-256-cbc -a -salt -pbkdf2 -in secrets.txt -out secrets.txt.enc
Decrypt:
openssl aes-256-cbc -d -a -pbkdf2 -in secrets.txt.enc -out secrets.txt.new
More details on the various flags
Better Alternative: GPG
Though you have specifically asked about OpenSSL 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:
To Encrypt:
gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data
To Decrypt:
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.
RE: OpenSSL - Short Answer
You likely want to use gpg instead of openssl so see "Additional Notes" at the end of this answer. But to answer the question using openssl:
To Encrypt:
openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data
To Decrypt:
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.
RE: 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 <password>
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 <filename>
Read the password from the first line of <filename> 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.
Encrypt:
openssl enc -in infile.txt -out encrypted.dat -e -aes256 -k symmetrickey
Decrypt:
openssl enc -in encrypted.dat -out outfile.txt -d -aes256 -k symmetrickey
For details, see the openssl(1) docs.
DO NOT USE OPENSSL DEFAULT KEY DERIVATION.
Currently the accepted answer makes use of it and it's no longer recommended and secure.
It is very feasible for an attacker to simply brute force the key.
https://www.ietf.org/rfc/rfc2898.txt
PBKDF1 applies a hash function, which shall be MD2 [6], MD5 [19] or
SHA-1 [18], to derive keys. The length of the derived key is bounded
by the length of the hash function output, which is 16 octets for MD2
and MD5 and 20 octets for SHA-1. PBKDF1 is compatible with the key
derivation process in PKCS #5 v1.5. PBKDF1 is recommended only for compatibility with existing
applications since the keys it produces may not be large enough for
some applications.
PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
example) to derive keys. The length of the derived key is essentially
unbounded. (However, the maximum effective search space for the derived key may be limited by the structure of the underlying
pseudorandom function. See Appendix B.1 for further discussion.)
PBKDF2 is recommended for new applications.
Do this:
openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in hello -out hello.enc -k meow
openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in hello.enc -out hello.out
Note: Iterations in decryption have to be the same as iterations in encryption.
Iterations have to be a minimum of 10000.
Here is a good answer on the number of iterations: https://security.stackexchange.com/a/3993
Also... we've got enough people here recommending GPG. Read the damn question.
As mentioned in the other answers, previous versions of openssl used a weak key derivation function to derive an AES encryption key from the password. However, openssl v1.1.1 supports a stronger key derivation function, where the key is derived from the password using pbkdf2 with a randomly generated salt, and multiple iterations of sha256 hashing (10,000 by default).
To encrypt a file:
openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename
To decrypt a file:
openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
Note: An equivalent/compatible implementation in javascript (using the web crypto api) can be found at https://github.com/meixler/web-browser-based-file-encryption-decryption.
Update using a random generated public key.
Encypt:
openssl enc -aes-256-cbc -a -salt -in {raw data} -out {encrypted data} -pass file:{random key}
Decrypt:
openssl enc -d -aes-256-cbc -in {ciphered data} -out {raw data}
To Encrypt:
$ openssl bf < arquivo.txt > arquivo.txt.bf
To Decrypt:
$ openssl bf -d < arquivo.txt.bf > arquivo.txt
bf === Blowfish in CBC mode
There is an open source program that I find online it uses openssl to encrypt and decrypt files. It does this with a single password. The great thing about this open source script is that it deletes the original unencrypted file by shredding the file. But the dangerous thing about is once the original unencrypted file is gone you have to make sure you remember your password otherwise they be no other way to decrypt your file.
Here the link it is on github
https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py
Note that the OpenSSL CLI uses a weak non-standard algorithm to convert the passphrase to a key, and installing GPG results in various files added to your home directory and a gpg-agent background process running. If you want maximum portability and control with existing tools, you can use PHP or Python to access the lower-level APIs and directly pass in a full AES Key and IV.
Example PHP invocation via Bash:
IV='c2FtcGxlLWFlcy1pdjEyMw=='
KEY='Twsn8eh2w2HbVCF5zKArlY+Mv5ZwVyaGlk5QkeoSlmc='
INPUT=123456789023456
ENCRYPTED=$(php -r "print(openssl_encrypt('$INPUT','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$ENCRYPTED='$ENCRYPTED
DECRYPTED=$(php -r "print(openssl_decrypt('$ENCRYPTED','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$DECRYPTED='$DECRYPTED
This outputs:
$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456
You could also use PHP's openssl_pbkdf2 function to convert a passphrase to a key securely.