Using openssl encryption for Apple's HTTP Live Streaming - problem - encryption

This is my code of my shell script when static.key contains my random key.
hexKey=$(cat static.key | hexdump -e '16/1 "%02x"')
echo $hexKey
hexIV="0"
echo $hexIV
openssl aes-128-cbc -e -in logo-1.ts -out logo-enc-1.ts -p -nosalt -K ${he-iv ${hexIV}
I get some error when running it.
(output:
non-hex digit
invalid hex iv value
: command not found
)
Maybe someone knows the problem. I'm on it for days now.

That error means that the value OpenSSL sees for the IV contains a non-hexadecimal character (i.e., something other than 0123456789abcdefABCDEF).
An AES128 key is 128/8 = 16 bytes, so you should have 32 characters for the key. An IV is 16 bytes, corresponding to the AES block size, and OpenSSL will covert a single "0" into 16 zero bytes for you. This is an example of a good command:
$ echo -n "hello" > in
$ openssl aes-128-cbc -e -in in -out out -p -nosalt \
-K 000102030405060708090a0b0c0d0e0f -iv 000102030405060708090a0b0c0d0e0f
$ cat out | hexdump -e '16/1 "%02x"'
8326dc340c564d49790650a59260fea0
Now replace the last character of the IV with a non-hex character, and see that you get the same error you're getting.
$ openssl aes-128-cbc -e -in in -out out -p -nosalt \
-K 000102030405060708090a0b0c0d0e0f -iv 000102030405060708090a0b0c0d0e0q
$ cat out | hexdump -e '16/1 "%02x"'
non-hex digit
invalid hex iv value
If what you've pasted is the real code you're running, the problem is obvious. First, what is -K ${he-iv ${hexIV} supposed to mean? Second, the argument -K is to give the key. You're missing -iv to give the IV. You're even missing a closing brace.
This will probably fix your problem assuming static.key has 16 bytes:
openssl aes-128-cbc -e -in logo-1.ts -out logo-enc-1.ts -p -nosalt -K $hexKey -iv $hexIV
As a last tip, if you're using bash, run your script with -x as the argument to bash and it will print every line it executes after it expands the variables so you can see exactly what it's doing:
$ /bin/bash -x my_script
+ hexKey=0
+ hexIV=0
+ openssl aes-128-cbc -e -in in -out out -p -nosalt -K 0 -iv 0

In the process of storing the key value in the bash shell, some trailing garbage got included (either a null or newline) which is being passed to openssl and causing it to complain about non hex characters.
To fix this for 128 bit / 32 ascii character hex keys and IVs, tell bash to pass ONLY the first 32 characters like this (for other key or iv lengths change the value from 32 to 1/4 the number of bits in the key or iv)
openssl aes-128-cbc -e -in logo-1.ts -out logo-enc-1.ts -p -nosalt -K ${hexKey:0:32} -iv ${hexIV:0:32}
To verify that the correct values are being passed, use openssl's 'print keys' -P option (note UPPER CASE "-P")
openssl aes-128-cbc -e -in logo-1.ts -out logo-enc-1.ts -p -nosalt -K ${hexKey:0:32} -iv ${hexIV:0:32} -P

I have been struggling with this, basically I found this solution:
Encrypt:
openssl aes-256-cbc -k “choose_password_to_encrypt” -in /path_to_your_file_to_encrypt/file_to_encrypt.extension_file -out /path_to_your_file_to_dencrypt/choose_name_file_after_decrypt.extension_file.enc -a
Decrypt:
openssl aes-256-cbc -k “password_chose_to_encrypt” -in /path_to_your_file_to_dencrypt/choose_name_file_after_decrypt.extension_file.enc -d -a -out /path_to_your_file_to_encrypt/file_to_encrypt.extension_file
I hope it can be useful

Related

Failed to decrypt AES encrypted file by Javascript using OpenSSL

The ciphertext is encrypted by Javascript using the AES algorithm in hexadecimal format. I first coded it in Base64 and then decrypted it using OpenSSL.
But it failed, I don't know where it is wrong.
And I am using a Windows compiled version of OpenSSL.
http://gnuwin32.sourceforge.net/packages/openssl.htm
The command is as follows:
openssl enc -aes-128-cbc -a -A -in Cipherbase64.txt -out PlainText.txt -K 31323334353637383930303030303030 -iv 31323334353637383930303030303030 -d
result:
bad decrypt
6396:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:./crypto/evp/evp_enc.c:461:
Ciphertext (HEX)
4cb4eb49df960e82c14e158ac418ca918736e4fbb730f532fc37d226e0e8b0e3ce0571ce4c146a6a9e037b9b79d8077568326d7fe2a3f9a91d266cfeb8bfac5668f526bc4d5ee1a21cbe85c8efab8cd1fe29b4a2b412468c6d97b7a3bfd2f69c50691e181fde43710bc61ffff2c6e7cbab59de70b97d993707c16e4a909273cc873d9156dda0ad03214e29048ac39532b8ec11c071174219fefa85e0d489468036154d19d2b683b20b07589abb9f4d863fcd17598d43a8b82d37236ceee7588d08a22f4c9662bba7f4cf6595f28b0e7b7e62f9be2d42f1b11f5c06aca7ed7568d8922d9155c229a8d57b251695c2bd645cb44539e4278b4431ac60a318fbd22afe18b204f9730f86a07c43355ce89f9646be5810e0c6bd2043066d359efe73c8e0ac7f581e048ed1809ad2720ea96f528d0acc7fd622b86d3073e8b1ac0b5d70f4e92b045e8cdf1fb6c999332ba2c279ebab2262589082a8214187a8904671a2c4eec8828335dc7f49fe438fb4e34c762e9f7febe30672a9ced8b0a2b66373d3a3b9efbe46e63f4d8b2723ebe85736f5
Thanks to Topaco for your help. Because of my negligence, mistake CTR for CBC, causing confusion.
You can try the following:
openssl enc -aes-128-cbc -a -A -in Cipherbase64.txt -out PlainText.txt -K 31323334353637383930303030303030 -iv 31323334353637383930303030303030 -d
After the -K and -iv options, the input must be a hexadecimal string, i.e. instead of 1234567890000000 you have to use 31323334353637383930303030303030. The -A option says that the Base64-encoded ciphertext is contained in one single line, here. So there is no need to use line breaks.
Update:
It turned out that the JavaScript-code actually applied to generate the posted ciphertext uses CTR-mode for encryption (instead of CBC-mode). Therefore, the OpenSSL-statement which can be used to decrypt the posted ciphertext is:
openssl enc -aes-128-ctr -a -A -in Cipherbase64.txt -out PlainText.txt -K 31323334353637383930303030303030 -iv 31323334353637383930303030303030 -d
The decrypted text is:
{"sign":"13adab9285fe86206b73e029ff0d290fc0e31237","timestamp":1570608017,"logid":"MTU3MDYwODA2MjAzMjAuMTMzMjE0Nzc2OTIxNTgxNDY=","uk":3012946979,"shareid":547370362,"fid_list":"[\"482622974717034\"]","input":"aaxb","vcode":"33324238656332346361663334656637323237633636373637643239666664336662393132313032313738303030303030303030303030303031353730363038303530B0D6C0036A1909217D2CDCD5B76B46FB"}
which can be easily verified here.

Openssl decryption not working

I am trying to encrypt and decrypt text from command line using openssl. I am able to encrypt the text but I am not able to decrypt it back.
Here is how I am encrypting my text from command line:
➜ ~ echo -n 'Foo Bar' | openssl enc -aes-128-ecb -K 123456789 | openssl enc -base64
Above command gives me following output:
RxmxBbcIFm5ZMiQIBYDr4Q==
Here is how I am trying to decrypt my text:
➜ ~ echo -n 'RxmxBbcIFm5ZMiQIBYDr4Q==' | openssl enc -aes-128-ecb -K 123456789 | openssl enc -base64 -d
When I run the above command, I am not getting any output displayed on the screen:
➜ ~
Any idea how to decrypt the code from terminal?
Thanks
Problem in -n flag in echo command. openssl required \n symbol for successful decryption.
compare
$ echo 'Foo Bar' | openssl enc -e -aes-128-ecb -base64 -K 123456789
eoGjHSco3ee2nOjibu7a3g==
and
echo -n 'Foo Bar' | openssl enc -e -aes-128-ecb -base64 -K 123456789
RxmxBbcIFm5ZMiQIBYDr4Q==
so it affects both, encryption and decryption.
$echo eoGjHSco3ee2nOjibu7a3g== | openssl enc -d -base64 -aes-128-ecb -K 123456789
Foo Bar
$
and
echo RxmxBbcIFm5ZMiQIBYDr4Q== | openssl enc -d -base64 -aes-128-ecb -K 123456789
Foo Bar$
This part:
openssl enc -aes-128-ecb -K 123456789
outputs raw data. When you try to decrypt it, you're adding -base64. The output isn't base64, so it fails. In your particular case, what you seem to mean is this:
echo -n 'Foo Bar' | openssl enc -aes-128-ecb -K 123456789 | openssl enc -aes-128-ecb -d -K 123456789
To encrypt and output base64, you want:
echo -n 'Foo Bar' | openssl enc -aes-128-ecb -K 123456789 -base64
To decrypt and accept base64, you want:
echo 'RxmxBbcIFm5ZMiQIBYDr4Q==' | openssl enc -d -aes-128-ecb -K 123456789 -base64
As user1516873 notes, to use base64 input, you need a trailing newline, so no -n, but that wasn't the major problem in your code. It only applies to Base64, not generally to encryption or decryption. You could also use -A and not pass a newline. -base64 is the same as -a, which is expecting a multi-line base64 block, while -A expects it all on one line (so doesn't need the \n).

OpenSSL string decryption issue

I'll try to make this succinct as possible.
I want to be able to encrypt & decrypt simple strings using OpenSSL, which I have done before.
HOWEVER, the following conditions must be met:
Simple passphrase use (no keys)
No input/output files
No prompt for passphrase (specify via command-line options for either direction)
I'm 50% there. I can successfully perform ENCRYPTION via:
echo 'someTextIWantToEncrypt' | openssl enc -e -aes-256-cbc -nosalt -pass pass:mySecretPass
The output result is:
(??b}n??v???>??G??.?B??~?
OK, great. Now I want to DECRYPT that string. So I do:
echo -n '(??b}n??v???>??G??.?B??~?' | openssl enc -d -aes-256-cbc -pass pass:mySecretPass
or even as an alternative:
openssl enc -d -aes-256-cbc -pass pass:mySecretPass <<< '(??b}n??v???>??G??.?B??~?'
But I get this response:
bad magic number
Though I don't want to use input/output files, that method DOES work 100%:
# encrypt to file
echo -n 'someTextIWantToEncrypt' | openssl enc -e -nosalt -out test.txt -aes-256-cbc -pass pass:mySecretPass
# decrypt from file
openssl enc -d -nosalt -in test.txt -aes-256-cbc -pass pass:mySecretPass
# result of decryption (is successful):
someTextIWantToEncrypt
So ... how can I achieve the above decryption process without using input/output files whatsoever? I feel I am close, but missing some small detail.
Thanks in advance.
The problem is that encryption uses the entire ASCII character set, including unprintable characters. If you want to be able to cut and paste the encrypted data, you need to convert it to only printable characters. You can do this with the -base64 (or -a) option:
echo 'someTextIWantToEncrypt' | \
openssl enc -base64 -e -aes-256-cbc -nosalt -pass pass:mySecretPass
KPkBkGJ9bs4YHvh24xz7m9jTlYWm1LcIFcWR0DwY4PU=
Then decrypt it the same way:
echo "KPkBkGJ9bs4YHvh24xz7m9jTlYWm1LcIFcWR0DwY4PU=" | \
openssl enc -base64 -d -aes-256-cbc -nosalt -pass pass:mySecretPass
WARNING: If you're using openssl, I can only assume the confidentiality of the data, and therefore the password, is important to you. If that's the case, you should never supply a password on the command line, because it can be exposed to anyone with the privilege to run ps.
A better solution is to store the password in an environment variable and have openssl read it from there:
export passwd="mySecretPass"
echo "KPkBkGJ9bs4YHvh24xz7m9jTlYWm1LcIFcWR0DwY4PU=" | \
openssl enc -base64 -d -aes-256-cbc -nosalt -pass env:passwd
Decrypt
#!/bin/bash
clear
# encrypt to file
echo "enter choice "
echo "1-dakr"
echo "2-gakr"
read choice
case $choice in
1 )
echo "text?"
read text
echo "pass?"
read pass
echo -n '$text' | openssl enc -e -nosalt -out test.txt -aes-256-cbc -pass pass:$pass
;;
2 )
# decrypt from file
echo "pass?"
read pass
echo "path?"
read path
openssl enc -d -nosalt -in $path -aes-256-cbc -pass pass:$pass
;;
* )
echo "shcd"
;;
esac
Output of Decrypt is $text how to fix it?
I know this is old, but someone else just showed me this question. I have a TCL script that achieves this easily, and can just be modified to work with whatever shell you're using, it contains these lines:
if {[catch {set lines [exec echo -n $tte | openssl enc -$cipher -a -pbkdf2 -iter $iterations -pass pass:$fkey]} msg]} {
tk_messageBox -message $msg
return
}
Where $tte = text to encrypt, $cipher and $iterations are self explanatory, and $fkey is the password passed to openssl. Just add a -d switch to decrypt.

How can I measure the elapsed time when ecnrypting using Openssl in linux

I don't know how could I measure the elapsed time in encryption using openssl.
I have downloaded openssl to my linux system with no problems and I can do encryption to different files but I don't know how to measure the time to see what encryption algorithm is more effecient.
Here is the command that I use to do the encryption:
OpenSSL> enc -des-cbc -salt -a -in "/usr/local/openssl/file1.txt" -out "/usr/local/openssl/file1_des.enc" -k "123456"
This is the other algorithm:
OpenSSL> enc -aes-128-cbc -salt -a -in "/usr/local/openssl/file2.txt" -out "/usr/local/openssl/file2_aes.enc" -k "123456"
Is there a way to measure the time of execution? I tried to open another terminal and execute the (time) but it didn't help. I also don't have that much of experice on using linux. However, I tried to do the same thing on Windows but still don't have a way to measure the time.
Hope you guys can help.
Thanks,
D
Eh, you mean like openssl speed?
On Linux, I entered this at the shell prompt:
time openssl enc -des-cbc -salt -a -in foo.txt -out foo_des.enc -k "123456"
and got the output:
real 0m0.214s
user 0m0.008s
sys 0m0.016s
That said, you'd get a more meaningful result if you introduced some sort of looping construct. At the very least, consider creating a text file with multiple openssl command lines:
opensslcmds.txt:
enc -des-cbc -salt -a -in foo.txt -out file1_des.enc -k 123456
enc -des-cbc -salt -a -in foo.txt -out file2_des.enc -k 123456
enc -des-cbc -salt -a -in foo.txt -out file3_des.enc -k 123456
(and so on)
and then run
time openssl < opensslcmds.txt

Using openssl encryption for Apple's HTTP Live Streaming

Has anyone had any luck getting encrypted streaming to work with Apple's HTTP Live Streaming using openssl? It seems I'm almost there but my video doesn't play but I don't get any errors in Safari either (like "Video is unplayable" or "You don't have permission to play this video" when I got the key wrong).
#bash script:
keyFile="key.txt"
openssl rand 16 > $keyFile
hexKey=$(cat key.txt | hexdump -e '"%x"')
hexIV='0'
openssl aes-128-cbc -e -in $fileName -out $encryptedFileName -p -nosalt -iv ${hexIV} -K ${hexKey}
#my playlist file:
#EXTM3U
#EXT-X-TARGETDURATION:000020
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.txt"
#EXTINF:20, no desc
test.ts.enc
#EXT-X-ENDLIST
I was using these docs as a guide:
https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming
Okay, I figured it out... My hexdump command was wrong. It should be:
hexKey=$(cat key.txt | hexdump -e '16/1 "%02x"')
Also keep in mind the following, if you have more than 1 TS "chunk", and you're looking for a bit-exact replacement for the Apple encryption pipeline. By default, the Apple encryption tool updates the IV (initialization vector) parameter for each of the chunks, which "increases the strength of the cipher," according to the Pantos spec.
Implementing this just means that the sequence number needs to be encoded in hex and passed as the -iv parameter to openssl:
#!/bin/bash
keyFile="key.txt"
openssl rand 16 > $keyFile
hexKey=$(cat key.txt | hexdump -e '"%x"')
# hexIV='0'
for i in {0..number_of_TS_chunks}
do
hexIV=`printf '%032x' $i`
openssl aes-128-cbc -e -in $fileName -out $encryptedFileName -p -nosalt -iv ${hexIV} -K ${hexKey}
done
Combining information from three of the above (the OP, the fix for hexdump and the IV information) yielded a working solution for us. Namely:
openssl rand 16 > static.key
key_as_hex=$(cat static.key | hexdump -e '16/1 "%02x"')
for i in {0..9}; do
init_vector=`printf '%032x' $i`
openssl aes-128-cbc -e -in video_low_$(($i+1)).ts -out video_low_enc_$(($i+1)).ts -p -nosalt -iv $init_vector -K $key_as_hex
done
Unfortunately I don't have the tools to experiment with this. It looks like you carefully followed the spec. One thing I would do is sniff the network do make sure the key.txt file is getting downloaded to Safari. I would also try explicitly picking the IV using the IV attribute of the EXT-X-KEY tag, e.g.
#EXT-X-KEY:METHOD=AES-128,URI="key.txt",IV=0x00000000000000000000000000000000

Resources