OpenSSL: Bad magic number using command line tool - windows

For background, I am working through the Matasano Crypto Challenges. One of the problems (Set1, Challenge 7) is to decrypt an AES-128 ECB mode file with a given key, YELLOW SUBMARINE.
The file is base64 encoded and I can decrypt the file in Python but I cannot using the Windows 10 openssl command line tool.
The command I am running is:
openssl aes-128-ecb -d -a -in 7.txt -pass pass:"YELLOW SUBMARINE"
When I run this I am told that I have a bad magic number.
Does anyone have an idea of why I am getting this error?

Looks like the -pass option doesn't like the space in the passphrase.
You can use the option -K with the hexadecimal key like this:
openssl aes-128-ecb -d -a -K 59454c4c4f57205355424d4152494e45 -in 7.txt
Or use the passphrase directly with this command:
openssl aes-128-ecb -d -a -in 7.txt -K $(echo -n "YELLOW SUBMARINE" | hexdump -v -e '/1 "%02X"')

Just for completeness: encrypting with -a params ( Perform base64 encoding/decoding (alias -base64) ) and decrypting without it ( or vice-versa ), bad magic number given.

Related

Openssl passin throws "Bad password read"

Trying to encrypt a file & make executable using openssl. Found an interesting link that was suitable to my problem with one issue. which is "I had to pass the password used for encryption in openssl command" which is resulting error.
Create Write your script (script-base.sh)
#!/bin/sh
echo "Hello World"
Encrypt your script (give a password): foobar is my password
openssl enc -e -aes-256-cbc -a -in script-base.sh > script-enc
Write de Wrapper (script-final.sh):
#!/bin/sh
openssl enc -d -aes-256-cbc -a -in script-enc | sh -passin pass:foobar
Running "script-final.sh" I see following error in console
enter aes-256-cbc decryption password: bad password read
Though the following code works but its deprecated
openssl enc -d -aes-256-cbc -a -in script-enc -k foobar | sh -
when used the following error is thrown
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
bad decrypt
... works but [] deprecated: openssl enc -d -aes-256-cbc -a -in script-enc -k foobar | sh -
In that case you give -k foobar as an option to the openssl enc -d command, so it is used as the password to decrypt, which succeeds since you did in fact encrypt using foobar as the password (and the same cipher and default KDF). See below about deprecation.
openssl enc -d -aes-256-cbc -a -in script-enc | sh -passin pass:foobar [gives]
enter aes-256-cbc decryption password: bad password read
Here you didn't give -passin pass:foobar as an option to openssl, you gave it as an option to the shell that is the second component of the pipeline. Since you didn't give the password as an argument to openssl and it is needed, openssl prompted you to input it, but you didn't give valid input (perhaps entering control-D or similar) so it failed. If you did instead
openssl enc -d -aes-256-cbc -a -in script-enc -passin pass:foobar | sh
it would work exactly the same as the -k version, except for taking more space in your script.
It is indeed true that the key-derivation long used (and still default) by openssl enc is very poor and weak and has been widely criticized for decades; OpenSSL 1.1.1 (released 2018, after the date of the answer you link to) and up finally offers a better method with -pbkdf2 and warns about using the old one. However, you should pay attention to this warning on the encrypt side rather than decrypt; once you've encrypted with the poor method, you must use it to decrypt (and suffer the warning). Also note, as I commented at that link, OpenSSL 1.1.x (and 3.0) are incompatible with earlier versions, so if any system(s) you or anyone (like your users if any) want this to work on are running older software it will fail.
Alternatively, consider using something that was properly designed in the first place, such as GPG which was recommended in the answer by Gilles on that same question (well over a year earlier). Although GPG, depending on the version, makes it less convenient to provide the password on the commandline because that usually allows it to be compromised -- but in your case you are already compromising it yourself, so GPG's attempt to give you security is wasted.

Hiding sensitive ruby shell commands

I'm using fastlane and sh command to decrypt some credentials but seems ruby prints the output in logs. How do I hide the sensitive information from logs?
cmd_decrypt = "openssl enc -aes-256-cbc -d -a -k \"#{ENV["MATCH_PASSWORD"]}\" -in #{enc_file} -out #{dec_file[0]}"
sh(cmd_decrypt)
output:
[09:38:15]: --------------------------------------------------------------------
[09:38:15]: Step: openssl enc -aes-256-cbc -d -a -k "PASSWORD_SHOWN!" -in /var/folders/7g/yy/T/d20190925-1304-1qv6cj1/vault/zz-out /var/folders/7g/yy/T/d20190925-1304-1qv6cj1/vault/xx
[09:38:15]: --------------------------------------------------------------------
[09:38:15]: $ openssl enc -aes-256-cbc -d -a -k "PASSWORD_SHOWN!" -in /var/folders/7g/yy/T/d20190925-1304-1qv6cj1/vault/zz -out /var/folders/7g/yy/T/d20190925-1304-1qv6cj1/vault/xx
You can pass sh extra parameters. In this case, you would call it like this:
sh(cmd_decrypt, log: false)
The documentation for sh is here: https://docs.fastlane.tools/actions/sh/
You get can get the docs for other built-in actions here:
https://docs.fastlane.tools/actions/
And the docs for other plugin's actions here: https://docs.fastlane.tools/plugins/available-plugins/
Since you have an environment variable, why not just run with that?
cmd_decrypt = "openssl enc -aes-256-cbc -d -a -k \"$MATCH_PASSWORD\" -in #{enc_file} -out #{dec_file[0]}"
sh(cmd_decrypt)
From there shell interpolation should take over and make it work. One thing to note is your -in parameter doesn't have shell escaping, which it usually must have, done using shellescape.
You really should be specifying these as separate arguments, though, whenever possible to avoid injection issues. The problem is you lose shell interpolation at that point.
The good news is you can always write a wrapper script to provide safety and ease of use, something like:
#!/bin/sh
# descrypt.sh
openssl enc -aes-256-cbc -d -a -k "$MATCH_PASSWORD" -in $1 -out $2
So then you can call it like this:
sh('descrypt.sh', enc_file, dec_file[0])
Now it logs something a lot quieter as well as a bonus. You can pick which arguments to pass through, or even throw them all through with $*.

Bash special character used in YAML file

I am struggling with some bash script that generates some Environment Variables for me. I am using it in .travis.yml file later.
My encrypted key looks like that:
someRandomCharacters
withNewLine
In Terminal I checked three possibilities.
echo "someRandomCharacters
withNewLine" | openssl enc -aes-128-cbc -a -salt -pass pass:SomePassword -base64 -d
and
echo "someRandomCharacters\nWithNewLine" | openssl enc -aes-128-cbc -a -salt -pass pass:SomePassword -base64 -d
will give me correct output.
echo "someRandomCharactersWithNewLine" | openssl enc -aes-128-cbc -a -salt -pass pass:SomePassword -base64 -d
This one above will return error reading input file
So far so good - I understand why it works like that. But when I try to enter any of abovementioned options - for example like that:
- SOME_ENV=`echo "someRandomCharacters\nWithNewLines" | openssl enc -aes 128-cbc -a -salt -pass pass:SomePassword -base64 -d`
into travis.yml, two last options will return error reading input file and the first one will crash the whole build due to incorrect .yaml syntax.
I've tried to use any of these three above + many more for example with "\n" as special character as I found in examples here on STO. Any of them would return error reading input file and none of them returned me decrypted SOME_ENV into travis. Is there any solution for that? Or maybe my poor experience with BASH and YAML blocks me for seeing obvious mistake?
While it's hard to tell what exactly the problem is given fake data, here are some data points:
dash (the shell you get if you just run sh on modern Linux distros) and bash behave differently in certain cases.
You should never assume that a code snippet runs with bash, because any number of reasons can cause it to be run with sh instead, and it's sometimes hard to tell.
Here's a script containing a \n sequence that works with sh but fails with bash:
$ cat myfile
echo "U2FsdGVkX19EB+D8no\n9+9bnl4dE5H2WbOUSvsGZjK7s=" | openssl enc -aes-128-cbc -a -salt -pass pass:MyPassword -base64 -d
$ sh myfile
My test data
$ bash myfile
error reading input file
If we instead use echo -e, we get the opposite result where dash fails and bash works:
$ cat myfile
echo -e "U2FsdGVkX19EB+D8no\n9+9bnl4dE5H2WbOUSvsGZjK7s=" | openssl enc -aes-128-cbc -a -salt -pass pass:MyPassword -base64 -d
$ sh myfile
error reading input file
$ bash myfile
My test data
This is why POSIX recommends not using echo. If we instead use printf, it works on both:
$ cat myfile
printf "U2FsdGVkX19EB+D8no\n9+9bnl4dE5H2WbOUSvsGZjK7s=\n" | openssl enc -aes-128-cbc -a -salt -pass pass:MyPassword -base64 -d
$ sh myfile
My test data
$ bash myfile
My test data
However, the line feed sequence in the middle is optional for openssl, and can just be removed (even though you seem to say that this doesn't work: maybe you removed the \ but not the n?)
$ cat myfile
echo "U2FsdGVkX19EB+D8no9+9bnl4dE5H2WbOUSvsGZjK7s=" | openssl enc -aes-128-cbc -a -salt -pass pass:MyPassword -base64 -d
$ sh myfile
My test data
$ bash myfile
My test data

Openssl aes-256-cbc in bash script

I want to encode randomly generated token with aes-256-cbc in bash. When I write this code in shell:
echo -n 8724eb94-ff8f-441e-81a7-bc4282f7c342 | openssl enc -a -e -aes-256-cbc -nosalt -pass pass:fzJKp5/vYUWZUZ1hVSXycdmskKcSNtmZoFhPv5UtWGuoV9yH61JCjKzXUWmRCJJ9FITOi66ANSDpBJZKjrRFjA==
I get: HdkTpAnsJ+bHi0DggaQq3iJMh0mrgcohOiJDeGzpqLFdvZUEXaD3YBEqGa4rBB7Y - and it is the same as in Node.js crypto module.
But! When I write this code in bashscript:
hash=$(echo -n 8724eb94-ff8f-441e-81a7-bc4282f7c342 | openssl enc -a -e -aes-256-cbc -nosalt -pass pass:fzJKp5/vYUWZUZ1hVSXycdmskKcSNtmZoFhPv5UtWGuoV9yH61JCjKzXUWmRCJJ9FITOi66ANSDpBJZKjrRFjA==);
echo ${hash}
I get alphrNunU02O4Xxw+qVgaEEaZGTrdGenvgsGnt0lczOkGKX5l6rAQTY3EJ8VA0iB and I have no idea why and where is bug. I have tried using ``, but with same wrong encoded value.
I have never write anything in bash, so I have no idea about some "tricks".
Thank you for any answers!
I figured it out. I have using:
'sh script.sh'
to run my script. But when I have done this:
'bash script.sh'
everything works perfectly. I have no idea why (yet) and now I will look for answer for 'What is thy difference between 'sh' and 'bash' '.
Thank you for some suggestions!

OpenSSL Command Line Tool: "-in" argument from string

How can I trick the -in argument of the OpenSSL command line tool in order to get data from string instead a file?
Normally, I could use echo command to do it:
echo 'test string 1' | openssl enc -aes-256-cbc -a -salt -pass pass:mypassword
Is there a way I can do it without echo and pipe? Similar to the -pass pass: argument?
Thanks in advance!
If your shell is bash and your OS supports it, you can use process substitution:
openssl enc -in <(echo 'test string 1') -aes-256-cbc -a -salt -pass pass:mypassword
I found a way to go around this! Instead of passing everything before and since openssl has an interactive mode, it's possible to run the command without input:
openssl enc -aes-256-cbc -a -salt -pass pass:mypassword
And OpenSSL will be waiting for data to encrypt. This can be also useful for streams!
Then type in the string or data you want to encrypt and send a EOT (End of Transmission) in Terminal is usual ^D Control+D it it will output to stdout the encrypted string!
Hope this may help someone some day!

Resources