Hls.js: Manual AES-key injection

Created on 24 Jan 2017  路  6Comments  路  Source: video-dev/hls.js

Hi.

I have a VOD files where fragments (ts) encrypted with custom key (AES). Key URL is not presented inside m3u8 files, though I need to put it in manually.
Is it possible to use manual AES-key injection in the lib?

Question Wontfix

Most helpful comment

If someone interested, I did the trick:

  1. Replaced config.loader with mine code
  2. Catch manifest success resonse and replace EXT-X-KEY with fake url
  3. Catch fake key url request and response with custom key

Here is the code (sorry for coffee):

## external crypto key support start
str2ab = (str) ->
  buf = new ArrayBuffer(str.length) 
  bufView = new Uint8Array(buf)
  for ind in [0..str.length-1]
    bufView[ind] = str.charCodeAt(ind)
  return buf

hls.config.__loader = hls.config.loader
hls.config.loader = ->
  xhrLoader = new hls.config.__loader(hls)
  src = currentSource
  if src && src.crypto
    xhrLoader._load = xhrLoader.load
    xhrLoader.load = ->
      if arguments[0].url == 'crypto://decrypt'
        src.crypto.key_raw = str2ab(src.crypto.key) if src.crypto.key_raw == undefined
        arguments[2].onSuccess.apply(this, [
          {data: src.crypto.key_raw, url: arguments[0].url},
          {},
          arguments[0]
        ])
      else
        if arguments[0].type == 'manifest'
          onSuccess = arguments[2].onSuccess
          arguments[2].onSuccess = ->
            arguments[0].data = arguments[0].data.replace(/#EXT-X-KEY[^#]/gm,'#EXT-X-KEY:METHOD=' + src.crypto.method + ',URI=crypto://decrypt\n')
            onSuccess.apply(this,arguments)
        xhrLoader._load.apply(this, arguments)
  return xhrLoader
## external crypto key support end

currentSource example:

{src: '//mydomain/video.m3u8', crypto: {method: 'AES-128', key: 'VeryVerySecretKey'}}

Looks awkwardly, but works.

All 6 comments

yes you could override xhrLoader in config.loader, catch key URL request, and provide AES key from another mean.

If someone interested, I did the trick:

  1. Replaced config.loader with mine code
  2. Catch manifest success resonse and replace EXT-X-KEY with fake url
  3. Catch fake key url request and response with custom key

Here is the code (sorry for coffee):

## external crypto key support start
str2ab = (str) ->
  buf = new ArrayBuffer(str.length) 
  bufView = new Uint8Array(buf)
  for ind in [0..str.length-1]
    bufView[ind] = str.charCodeAt(ind)
  return buf

hls.config.__loader = hls.config.loader
hls.config.loader = ->
  xhrLoader = new hls.config.__loader(hls)
  src = currentSource
  if src && src.crypto
    xhrLoader._load = xhrLoader.load
    xhrLoader.load = ->
      if arguments[0].url == 'crypto://decrypt'
        src.crypto.key_raw = str2ab(src.crypto.key) if src.crypto.key_raw == undefined
        arguments[2].onSuccess.apply(this, [
          {data: src.crypto.key_raw, url: arguments[0].url},
          {},
          arguments[0]
        ])
      else
        if arguments[0].type == 'manifest'
          onSuccess = arguments[2].onSuccess
          arguments[2].onSuccess = ->
            arguments[0].data = arguments[0].data.replace(/#EXT-X-KEY[^#]/gm,'#EXT-X-KEY:METHOD=' + src.crypto.method + ',URI=crypto://decrypt\n')
            onSuccess.apply(this,arguments)
        xhrLoader._load.apply(this, arguments)
  return xhrLoader
## external crypto key support end

currentSource example:

{src: '//mydomain/video.m3u8', crypto: {method: 'AES-128', key: 'VeryVerySecretKey'}}

Looks awkwardly, but works.

Do you have complete support for AES-128 playing demo?I'm trying, THX

Good Answer but i have some doubt clearify.

I encrypt m3u8 throgugh ffmpeg. but it plays well but my key is not secure. it expose in hardcoded file file like https://xyz.com/info.key.
How can i secure decryption key without write on harddisk path.
Plz explain full code.
Thanks in Advance

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Hello- We would like to use this code for our AES-128 encrypted hls.js player. We are not too experienced with js (although we have an encrypted player running now) and had some questions.

  1. Is crypto a js Library we have to load first?
  2. Where do we insert the actual key which we used to create the hls chunks in the first place? That needs to replace the EXT-X-KEY URI in the manifest (fake) and injected to the player.
  3. What are the variables we need to replace in the code with each new video we play? We understand src: in currentSource example, but how about VeryVerySecretKey, is that the actual key we used to encrypt the hls video chunks in the first place?
    Thanks
Was this page helpful?
0 / 5 - 0 ratings