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
Related
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.
I need to encrypt a file containing one CLIENT_ID by line.
When I use
openssl enc -k jesuislacle -aes256 -base64 -e -in &_fidat/num_tie_dmp.csv -out &_fidat/decrypted_numtie.csv, I encrypt the whole file.
But what I want is to encrypt line by line. i.e.
Original I have:
ABCDEC
FGHHIJ
KLMNOP
QRSTUV
What I want :
QHXrpv3ah0qEPBECCt1//PBKiugmWYMuE+WaA4r9Rgc#
nAca0Pb6bH1cQRfkO9wReY+X6dgl44BKE/nKSFBLM+o#
UjTJsoHoLAC0GeqqImxDXX9znUtd7dGm4VODZ+T7lvM#
dcU+H+jd9RZZqweDu1nnJDWMlKjxW2Hc+Q2uAW1tQfk#
For the moment, I launch this command X times for each ID.
But I can have, more than 10000 ID to encrypt. It takes few hours to have the results. It's too much.
What's the best way.
I'm on SAS 9.3, UNIX and I have to encrypt in AES 256 not MD5 (thank's to my DPO :-) )
Thanks for your help.
Jérome
You can try this:
while read line; do
echo "$line" | openssl enc -k jesuislacle -aes256 -base64 -e;
done <infile >outfile
It reads all lines of the file one by one and encrypts it with the specified key.
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 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
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