Decrypt M3U8 Playlist Encrypted With Aes-128 Without Iv

Decrypt M3U8 Playlist encrypted with AES-128 without IV

The HLS spec states [1]:

An encryption method of AES-128 signals that Media Segments are
completely encrypted using the Advanced Encryption Standard (AES)
[AES_128] with a 128-bit key, Cipher Block Chaining (CBC), and
Public-Key Cryptography Standards #7 (PKCS7) padding [RFC5652].
CBC is restarted on each segment boundary, using either the
Initialization Vector (IV) attribute value or the Media Sequence
as the IV; see Section 5.2.

So you have to use the value of the EXT-X-MEDIA-SEQUENCE tag in the variant playlist. Be sure to extrapolate, i.e. increment it for each segment.


How to decrypt AES-128 encrypted m3u8 video files?

In order to decrypt encrypted video stream you need encryption key.
This key is not part of the stream. It should be obtained separately.

EXT-X-FAXS-CM header contains DRM meta-data and not the key.

This is excert from Adobe Media Server developer guide:
The Adobe Access Server protected variant playlist also needs to include the #EXT-X-FAXS-CM tag. The value of #EXT-X-FAXS-CM tag in variant playlist is the relative URI referring to the DRM metadata of one of the individual streams.At the client, the #EXT-X-FAXS-CM tag in variant playlist will be used to create the DRM session. The same DRM session will be used for all encrypted M3U8 files inside the variant playlist.

Full guide can be found here:

There is also mention that faxs:// URI is for local key serving.
So key obtained locally from a device.

How to decrypt AES-128 encrypted m3u8 TS files

There was already a similar quesion here (unable to find it back)

how to find salt or block size

Look at your EXT-X-KEY header. It states AES-128, so you will have to use AES-128 (it's the key size, block size is always 128 bit).

According to the RFC by default CBC mode with Pkcs7 padding is used.

The section EXT-X-KEY further states: the Initialization Vector (IV) attribute value or the Media Sequence Number as the IV

So the IV should be present in the EXT-X-KEY header. If not, the sequence number is used (which is terrible idea for CBC, but this is how it is).

or basically we are doing it in correct way

Basically it looks ok (except the salt and key). I am not sure what is the encryption key. The encoded response from the server has 16 bites (128 bits) so I'd assume that can be the key (that you will have to find out yourself)

How to decrypt segmented parts .ts files which are encrypted with ffmpeg?

If you just want to do it manually you can just use openssl

openssl aes-128-cbc -d -in encrypted.ts -out decrypted.ts -nosalt -K 261daad184c6acf4a3a21393ds232e1a -iv <iv>

To do so you also need to get the IV from your output.m3u8 playlist file. It is a property on the #EXT-X-KEY tag in there. If it is not explicitly specified on that tag, then it is implicitly 0 for the first segment, 1 for the second, and so on.

Decrypting And Combining .ts Audio Files with .m3u8

I've had few free hours today and toyed with this. Long story short - that base64 key is AES encrypted. This additional encryption is done with key which is dynamically generated from device data... meaning that even if I have whole data folder from your device I wouldn't be able to decrypt it.

Now, when you posses rooted device with offline data that's another matter - you can obviously inject your code to intercept key when it's decrypted so content can start playing... which is how I got it.

When you have proper key, decryption and joining of *.ts files is trivial. I recommend that you use FFMPEG for this task, my C# code that I'm leaving for illustration works well works only in some cases (depending on how files are encoded):

var folder = "path_to_folder";
byte[] encryptionKey = File.ReadAllBytes(folder + "path_to_key.key");

var outputFile = "c:\\i_love_you_guys.ts";
using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
var files = Directory.GetFiles(folder, "*.ts");
for (int i = 0; i < files.Length; i++)
byte[] encryptionIV = new byte[16];
using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
using (var encryptor = aes.CreateDecryptor())
using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))

So, this turned out to be wild goose chase. What @aergistal says in his answer is completely valid as long as you have proper my.key. Thus focus on obtaining key in plain format and decryption will then be super easy.

Related Topics

Leave a reply