AWS MediaLive で HLS AES-128 暗号化！



今回は AWS MediaLive でそもそも HLS AES暗号化ってどーやんの？　とふと思って調べたところ、公式ドキュメントに詳しく記されておらず、コンソールの `info` をクリックしてもたいしたこと書いてないし、ggってもこれだ！　ってのが見つけられなかったので、自分でまとめることにしました。

AWS Elemental MediaLive User Guide
https://docs.aws.amazon.com/ja_jp/medialive/latest/ug/hls-group-fields.html

# AWS MediaLive 設定

MediaLive + MediaStore 使って配信する前提です。
MediaLive + WebDAV でも利用できますが、 MediaLive + MediaPackage の場合には MediaPackage 側で再パッケージされるので多分使えないような気がします（未確認）

尚、MediaLive で DRM 設定以外は完了している状態から始めていきます。

※　MediaLive + MediaStore 配信設定は streampack チームの影のドン hagi さんの記事を参照下さい。

[MediaLive->MediaStoreでライブ配信するには](https://qiita.com/khagi/items/ff8120c498a7d45338b1)

## DRM 設定

AWS Elemental MediaLive > Channels > Edit > Output groups で HLS groups を開きます。

<img width="422" alt="スクリーンショット 2018-06-29 16.13.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/172426/61ab9e55-6898-21ad-5be0-d7ea9bf6a216.png">

デフォルトでは以下のようになっているので各項目を設定していきます。

<img width="802" alt="スクリーンショット 2018-06-29 16.14.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/172426/9b3fdffa-547c-083a-f441-0363a0c6bbbc.png">

設定項目とその内容です。


| 設定項目      |       設定値 |    備考   |
|:-----------------|:------------------|:------------------|
| Encryption Type  |AES128             ||
| Key Format       |            空欄 |空欄だと"identity"が利用されます|
| Key Format Versions|         空欄 |省略可能|
| Include IV in Manifest  |   INCLUDE |INCLUDEでマニフェストにIVが記載されます|
| IV Source        | FOLLOWS_SEGMENT_NUMBER|FOLLOWS_SEGMENT_NUMBERの場合、セグメント番号に合致するようにセグメントごとにIVが変更されます。EXPRICITでは任意IVを設定します             |
| Constant IV      |           空欄 |IV SourceでEXPRICITを選択した場合に任意の値を指定   |
| Key Provider Settings | Static key |            |
| Static Key Value |  任意の値 |16進32文字の値を指定            |
| Key Provider Server | Key Provider Server |            |
| URI | 任意の URI |key ファイルの場所 |
| Username |空欄|            |
| Password |空欄|            |

さて、気になるところを少し解説していきます。

## Static Key Value

MediaLive では勝手にキーを作ってくれないので自力で作成する必要があります。
16進32文字の値なので openssl で作ります。


```
$ openssl rand 16 > aes128.key
```
作成したキーから`Static Key Value` に設定する値を抽出します。

```
＄ xxd -ps aes128.key
122e96c6628d8757da801e2f12eb222b
```

この`122e96c6628d8757da801e2f12eb222b`を`Static Key Value`に設定します。



## URI

MediaLive では勝手にキーファイルを置いてくれないので上記で作成したキーファイルを S3 なり MediaStore なり Web Server なりで公開して、その URL を指定します。

例：

https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key

全部埋めるとこんな感じ！

<img width="673" alt="スクリーンショット 2018-06-29 17.48.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/172426/677f801f-5e9a-f3a0-b6d5-7a5c42548e31.png">


設定が完了したら `Update channel` でチャンネルを更新します。


# 視聴確認

## MediaLive

チャンネルを選択し、`Start` で開始します。

## Encoder

何でもよいですが今回は ffmpeg でファイルから擬似ライブ配信します。

```
$ ffmpeg -re -stream_loop -1 -i bigbuckbunny_1500.mp4 -vcodec copy -acodec copy -flags +loop-global_header -f flv "rtmp://xxx.xxx.xxx.xxx:1935/live/stream"
```
## Player

Safari で視聴します。

視聴 URL

```
https://xxxx.data.mediastore.ap-northeast-1.amazonaws.com/destA/test.m3u8
```

<img width="1121" alt="スクリーンショット 2018-06-29 17.23.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/172426/f96444a0-63a4-351f-0d02-51fdb5722291.png">

キーファイルを取得してるのが確認できます。
映像も復号化されて正常に表示されます。

### プレイリストファイル

m3u8 プレイリストの内容です。

```test_1.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:12
#EXT-X-MEDIA-SEQUENCE:21
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x00000000000000000000000000000015
#EXTINF:11.25000,
test_1_00021.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x00000000000000000000000000000016
#EXTINF:11.25000,
test_1_00022.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x00000000000000000000000000000017
#EXTINF:11.25000,
test_1_00023.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x00000000000000000000000000000018
#EXTINF:11.25000,
test_1_00024.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x00000000000000000000000000000019
#EXTINF:11.25000,
test_1_00025.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x0000000000000000000000000000001A
#EXTINF:11.25000,
test_1_00026.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x0000000000000000000000000000001B
#EXTINF:11.25000,
test_1_00027.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x0000000000000000000000000000001C
#EXTINF:11.25000,
test_1_00028.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x0000000000000000000000000000001D
#EXTINF:11.25000,
test_1_00029.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://s3-ap-northeast-1.amazonaws.com/{S3 bucket}/keys/aes128.key",IV=0x0000000000000000000000000000001E
#EXTINF:11.25000,
test_1_00030.ts
```

# まとめ

今回試してみてわかったことです。

- MediaLive はキーファイルを作成してくれない
- MediaLive はキーファイルを置いてもくれない
- 固定キーしか対応していないのでキーローテートはできない
- ドキュメントが優しくない

ETSでは HLS AES キーを生成できるのに MediaLive/MediaConvert では別途作成、配置する必要があります。
AES暗号化は市場で普通に使われている機能なので、同サービス内で完結できるようにしてくれると嬉しいところです。