I am trying to understand how the HTTP Live Streaming protocol that Apple supports on their iOS devices as well as on Safari protects the key that unlocks the content.
The way I understand it, the .m3u8 file holds the whole thing together and references the content (in MPEG2 TS container, AES 128 encrypted) and the key to the TS file.
Like in this example:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:7794
#EXT-X-TARGETDURATION:15
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"
#EXTINF:15,
http://media.example.com/fileSequence52-1.ts
#EXTINF:15,
http://media.example.com/fileSequence52-2.ts
#EXTINF:15,
http://media.example.com/fileSequence52-3.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=53"
#EXTINF:15,
http://media.example.com/fileSequence53-1.ts
Assuming a browser based playback where the <video>
element is fed a m3u8 file in the "src" attribute. In this case, even if the key is delivered via https, how can I make sure that the user does not simply enter the https URL in his browser and saves the key to his hard drive? The way I understand the mechanism, the key download is done by the <video>
tag as it plays the m3u8 source using the browser's https stack -- how is the legitimate client inside the browser distinguished from the user just typing it into the address bar? This must be really obvious, but I just don't see it...
All the best,
dansch
how can I make sure that the user does not simply enter the https URL in his
browser and saves the key to his hard drive?
You can have an SSL client key/certificate in the app, and thereby authenticate "the app" for playing the content. Then you'd avoid leaking your content to other devices than your app.
But that would mean you'd need to somehow hide your ssl-key/passphrase inside the app. And there are unfortunately also problems getting the video player on iOS to use the ssl key authentication...
The answer is not obvious at all. You're essentially required to invent your own key delivery if you want it to be secure. One option is to set a cookie for authorized users, and to verify the cookie in the key server. This will keep someone from being able to just use the key url to bypass your security.
Keep in mind that it still only takes one legitimate client to leak the key for your security to be invalidated.
The best way is to use Apple HLS supported encryption.HLS support 128 bit AES encryption and the client player need to decode the stream.
Some interesting pointers can be found here: https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/AirPlayGuide/EncryptionandAuthentication/EncryptionandAuthentication.html
This will require custom work in iOS, but also in Android and web players.
- Serve keys from a protected HTTPS realm. Before playback begins, your app can use NSURLConnection to authenticate itself, providing credentials that are kept hidden.
- Use cookies over HTTPS. Your app can make a connection to an HTTPS server and authenticate the app in an app-defined way. Your server can then issue a cookie that applies to the key URLs. You should set the cookie to expire long after playback is complete. The server must then require the presence of a valid session cookie in future GET requests for the keys.
For maximum reliability, if the expiration date is in the near future, the server should update the cookie’s expiration date in its response to future GET requests.
- Specify the keys in the .m3u8 files using an app-defined URL scheme. The app should register a custom NSURLProtocol to handle requests for those URLs. The player then calls back into your app when it needs to load a key URL; your app can then obtain the key using a secure side channel and can provide it to the player.
If you're only targeting iOS, then you should use Apple Fairplay DRM which handles the authentication of the keys.
how is the legitimate client inside the browser distinguished from the user just typing it into the address bar?
Interesting distinction, the suggestion is the browser the user is using is legitimate when playing the video embedded in the web page, and illegitimate when accessed via the address bar.
But there is no actual distinction there, I don't think you are missing anything.
How would you give rights to a browser and not a user? Cannot a user just write their own browser?
I know, it seems unlikely a user would write a browser, but these types of discussions are always about unlikely scenarios anyway. An unlikely user might find a way to view the m3u8 as plain text, they might download the keys directly, they may use those keys to unencrypt and eventual piece together the video segments.
Or, something that is far more likely - use screen recording software to copy any video that they can play in the browser.
In my opinion, if a user is authorized to play the video, they can, unfortunately also copy the video - because there's no way to prevent the display of the video being redirected into something that is no longer encrypted - at least in the environment of a desktop computer that is playing a video in a browser.
Anyway, my understanding is that you can protect the keys by requiring authorization to get the keys, but if the user has that authorization, then - well they can get the keys.
Have a look here
https://tools.ietf.org/html/draft-pantos-http-live-streaming-13#section-6.3.6
the playlist will have to specify a key tag for each segment. so a player will be able to identify a key required to decrypt a segment.
Browsers do not support DRM out of the box. HTML5 specify that it can be done via EME (Encrypted media extensions) whoever not implemented atm.
so your options are:
- use flash and fetch the keys via your own algorithm
- write your own plugins(extension)
- be big like Netflix and agree with browser
vendors to support your DRM aka content protection and key
distribution.
Apple's implementation of HTTP live streaming does not support DRM.
See FAQ number 16 on https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html