[FFmpeg-devel] About SAMPLE-AES encryption for m3u8

Andrea mariofutire at gmail.com
Sat Jun 20 20:35:56 EEST 2020


Been trying to figure out how to decrypt SAMPLE-AES and eventually hit an issue with my lack of 
understanding how H264 and ffmpeg work.

Example

https://d3iki3eydrtvsa.cloudfront.net/Chernobyl_20200618213021/HLS/Chernobyl_20200618213021_360.m3u8

(might be georestricted)

This is what it looks like

#EXTM3U
#EXT-X-VERSION:5
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://eyJDb250ZW50SWQiOiI5ODFjNmZmOC1jOTRiLTRmYTUtODY2Mi0zYmM2NmFkNWRjOTgiLCJLZXlJZCI6ImQzNWE2OWQ5LWIzYTItNGJjMC04MDQyLWQ2YTJiODVhODkzZCIsIklWIjoiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQT09In0=",KEYFORMAT="com.apple.streamingkeydelivery",IV=0x00000000000000000000000000000000
#EXTINF:10,
Chernobyl_20200618213021_360_00001.ts

and so on.

I think the skd:// actually contains all it is needed to decrypt.

A quick base 64 decode produces this

{'ContentId': '981c6ff8-c94b-4fa5-8662-3bc66ad5dc98',
  'KeyId': 'd35a69d9-b3a2-4bc0-8042-d6a2b85a893d',
  'IV': 'AAAAAAAAAAAAAAAAAAAAAA=='}

Further base 64 decoding of IV produces what looks like the IV to use.
KeyId is not so obvious, but again it contains 16 hex bytes (remove the "-") so it could be the key.

The container is *not* encrypted

ffprobe gives

Input #0, mpegts, from '/home/user/Sample.ts':
   Duration: 01:52:44.55, start: 2.006667, bitrate: 244 kb/s
   Program 1
     Stream #0:0[0x1e1]: Video: h264 (Main) ([219][0][0][0] / 0x00DB), yuv420p(progressive), 416x234 
[SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
     Stream #0:1[0x1e2](und): Audio: aac (LC) (apad / 0x64617061), 48000 Hz, stereo, fltp, 108 kb/s

So, reading this https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-07#section-4.4.4.4
and this 
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Encryption/Encryption.html#//apple_ref/doc/uid/TP40012862-CH2-SW7

It looks like the payload of the video frames *is* encrypted.

Now, someone with minimum understanding of the internals of ffmpeg could quickly do a bit of trial 
and error and check if any of the above is true.

I am happy to do it, but I have no idea where to find it in the code.
Is anybody available to help?


More information about the ffmpeg-devel mailing list