How to Encrypt Video for HLS

How to Encrypt Video for HLS

40 Replies

In this post, we’ll look at what encryption HLS supports and how to encrypt your videos with ffmpeg.

Encryption is the process of encoding information in such a way that only authorised parties can read it. The encryption process requires some kind of secret (key) together with an encryption algorithm.

There are many different types of encryption algorithms but HLS only supports AES-128. The Advanced Encryption Standard (AES) is an example of a block cipher, which encrypts (and decrypts) data in fixed-size blocks. It’s a symmetric key algorithm, which means that the key that is used to encrypt data is also used to decrypt it. AES-128 uses a key length of 128 bits (16 bytes).

HLS uses AES in cipher block chaining (CBC) mode. This means each block is encrypted using the cipher text of the preceding block, but this gives us a problem: how do we encrypt the first block? There is no block before it! To get around this problem we use what is known as an initialisation vector (IV). In this instance, it’s a 16-byte random value that is used to intialize the encryption process. It doesn’t need to be kept secret for the encryption to be secure.

Before we can encrypt our videos, we need an encryption key. I’m going to use OpenSSL to create the key, which we can do like so:

$ openssl rand 16 > enc.key

This instructs OpenSSL to generate a random 16-byte value, which corresponds to the key length (128 bits).

The next step is to generate an IV. This step is optional. (If no value is provided, the segment sequence number will be used instead.)

$ openssl rand -hex 16
ecd0d06eaf884d8226c33928e87efa33

Make a note of the output as you’ll need it shortly.

To encrypt the video we need to tell ffmpeg what encryption key to use, the URI of the key, and so on. We do this with -hls_key_info_file option passing it the location of a key info file. The file must be in the following format:

Key URI
Path to key file
IV (optional)

The first line specifies the URI of the key, which will be written to the playlist. The second line is the path to the file containing the encryption key, and the (optional) third line contains the initialisation vector. Here’s an example (enc.keyinfo):

https://hlsbook.net/enc.key
enc.key
ecd0d06eaf884d8226c33928e87efa33

Now that we have everything we need, run the following command to encrypt the video segments:

ffmpeg -y \
    -i sample.mov \
    -hls_time 9 \
    -hls_key_info_file enc.keyinfo
    -hls_playlist_type vod \
    -hls_segment_filename "fileSequence%d.ts" \
    prog_index.m3u8

Take a look at the generated playlist (prog_index.m3u8). It should look something like this:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:9
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-KEY:METHOD=AES-128,URI="https://hlsbook.net/enc.key",IV=0xecd0d06eaf884d8226c33928e87efa33
#EXTINF:8.33333
fileSequence0.ts
#EXTINF:8.33333
fileSequence1.ts
#EXTINF:8.33333
fileSequence2.ts
#EXTINF:8.33333
fileSequence3.ts
#EXTINF:8.33333
fileSequence4.ts
#EXTINF:5.66667
fileSequence5.ts
#EXT-X-ENDLIST

Note the URI of the encryption key. The player will retrieve the key from this location to decrypt the media segments. To protect the key from eavesdroppers it should be served over HTTPS. You may also want to implement some of authentication mechanism to restrict who has access to the key. If you’re interested, the book goes into some detail about how to achieve this. Click here to buy a copy.

To verify that the segments really are encrypted, try playing them using a media player like QuickTime or VLC. You shouldn’t be able to. Now run the command above without the encryption and then try playing a segment. Notice the difference.

In this instance, all the segments are encrypted with the same key. It can be beneficial to periodically change the encryption keys to minimise the impact if a particular key is exposed. This is known as key rotation, and the amount of time between successive key generations is referred to as the key rotation period.

To enable key rotation, set the -hls_flags option to periodic_rekey. When enabled, the key info file will be checked periodically. If the file has changed, segments will then be encrypted with the new encryption key. However, we still need to come up with a way of generating new keys and updating the key info file. Here’s an example of how it could be done:

#!/bin/bash
i=2
while true
do
    sleep 15
    tmpfile=`mktemp`
    openssl rand 16 > enc$i.key
    echo https://hlsbook.net/enc$i.key > $tmpfile
    echo enc$i.key >> $tmpfile
    echo `openssl rand -hex 16` >> $tmpfile
    mv $tmpfile enc.keyinfo
    let i++
done

The script uses the same values as before for the base URL (for each key) and key info file. It generates a new encryption key every 15 seconds, updating the key info file accordingly. (In practice you would choose a much longer key rotation period.)

To test it, run ffmpeg again but this time enable key rotation. At the same time, open a new terminal and run the script from the same directory. (The script will run forever until you terminate it.) When ffmpeg has finished, terminate the script.

Take a look at the playlist. You should now see a number of different key entries in the playlist. All the segments that follow a key tag (#EXT-X-KEY) are now encrypted using the key specified by the tag, instead of using one key to encrypt all segments like before.

Even though HLS supports encryption, which provides some sort of content protection, it isn’t a full DRM solution. If that kind of thing interests you then you may want to take a look at Apple’s FairPlay Streaming solution.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值