暗号化メディア拡張

W3C 作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-encrypted-media-2-20260515/
最新公開バージョン:
https://www.w3.org/TR/encrypted-media-2/
最新の編集者草案:
https://w3c.github.io/encrypted-media/
履歴:
https://www.w3.org/standards/history/encrypted-media-2/
コミット履歴
実装報告:
https://w3c.github.io/test-results/encrypted-media/all.html
最新の勧告:
https://www.w3.org/TR/2017/REC-encrypted-media-20170918/
編集者:
Joey Parrish (Google Inc.)
Greg Freedman (Netflix Inc.)
元編集者:
Mark Watson (Netflix Inc.) (2019年9月まで)
David Dorwin (Google Inc.) (2017年9月まで)
Jerry Smith (Microsoft Corporation) (2017年9月まで)
Adrian Bateman (Microsoft Corporation) (2014年5月まで)
フィードバック:
GitHub w3c/encrypted-media (プルリクエスト, 新しい課題, 未解決の課題)
public-media-wg@w3.org 件名行は [encrypted-media-2] … メッセージのトピック … (アーカイブ)

要約

この仕様は HTMLMediaElement [HTML] を拡張し、暗号化されたコンテンツの再生を制御するAPIを提供する。

このAPIは、単純なクリアキー復号から高価値動画までのユースケースをサポートする (適切なユーザーエージェント実装がある場合)。ライセンス/キー交換はアプリケーションにより制御され、 さまざまなコンテンツ復号および保護技術をサポートする堅牢な再生アプリケーションの開発を促進する。

この仕様は、コンテンツ保護またはデジタル著作権管理 システムを定義しない。むしろ、そのようなシステム、およびより単純なコンテンツ暗号化システムを 発見、選択、操作するために使用できる共通APIを定義する。この仕様への適合には デジタル著作権管理の実装は要求されない。共通の基準として実装が要求されるのは Clear Key システムのみである。

共通APIは、単純な一連のコンテンツ暗号化機能をサポートし、 認証や認可などのアプリケーション機能はページ作者に委ねる。これは、 暗号化システムとライセンスサーバーまたはその他のサーバーとの帯域外通信を仮定するのではなく、 コンテンツ保護システム固有のメッセージングをページによって仲介することを要求することで実現される。

この文書のステータス

このセクションは、この文書の公開時点における 文書のステータスを説明する。現在の W3C 公開物と、この技術報告の最新改訂版の一覧は、 W3C 標準および草案 索引で確認できる。

2017年9月W3C 勧告として公開されて以降、2つの新機能が追加された。

その他の機能の追加は、Media Working Group のスコープ外である。編集上の更新に加えて、 この仕様に加えられたその他の実質的な変更は、この仕様に対する保守上の課題に対処するものである。

前のバージョン以降に行われた変更の完全な一覧については、コミットを参照。

この文書は、Media Working Group により 勧告 トラックを使用する作業草案として公開された。

作業草案としての公開は、 W3C およびそのメンバーによる承認を意味しない。

これは草案文書であり、いつでも他の文書により更新、置換、または廃止される可能性がある。 この文書を進行中の作業以外のものとして引用することは不適切である。

この文書は、 W3C 特許 ポリシーの下で運営されるグループにより作成された。 W3C は、 グループの成果物に関連して行われた 特許開示の公開一覧を管理している。 そのページには、特許を開示するための指示も含まれる。個人が、当該個人が 必須クレームを含むと信じる特許について 実際の知識を有する場合、 W3C 特許ポリシー第6節に従って情報を開示しなければならない。

この文書は、 2025年8月18日版 W3C プロセス文書に準拠する。

1. はじめに

このセクションは非規範的である。

この仕様は、スクリプトがコンテンツ保護メカニズムを選択し、 ライセンス/キー交換を制御し、カスタムライセンス管理アルゴリズムを実行できるようにする。 各ユースケースごとに各ユーザーエージェントでクライアント側の変更を要求することなく、 幅広いユースケースをサポートする。これにより、コンテンツ提供者はすべてのデバイス向けに 単一のアプリケーションソリューションを開発できる。

サポートされるコンテンツは、コンテナー固有の「共通暗号化」仕様に従って暗号化され、 キーシステム間での使用を可能にする。サポートされるコンテンツは暗号化されていないコンテナーを持ち、 メタデータをアプリケーションへ提供できるようにし、他の HTMLMediaElement 機能との互換性を維持する。

実装者は、この仕様で述べられているセキュリティおよびプライバシー上の脅威と懸念に対する 緩和策に注意を払うべきである。特に、セキュリティおよびプライバシーに関する仕様要件は、 キーシステムとその実装のセキュリティおよびプライバシー上の性質を 理解せずには満たせない。8. 実装要件には、基礎となるキーシステム実装の統合および使用に関する セキュリティおよびプライバシー規定が含まれる。10. セキュリティは、 入力データやネットワーク攻撃などの外部脅威に焦点を当てる。11. プライバシーは、 ユーザー固有情報の取り扱い、およびユーザー自身のプライバシーに対する十分な制御を ユーザーに提供することに焦点を当てる。

この仕様はメディアデータのソースから独立しているが、作者は、多くの実装が Media Source Extensions [MEDIA-SOURCE] 経由で提供されたメディアデータの 復号のみをサポートしていることに注意すべきである。

このAPIを使用して実装される汎用スタックを以下に示す。この図はフローの例を示しており、 API呼び出しとイベントの他の組み合わせも可能である。

提案されたAPIを使用して実装された汎用スタック

2. 定義

コンテンツ復号モジュール (CDM)

コンテンツ復号モジュール(CDM)は、1つ以上のキーシステムに対して、 復号を含む機能を提供するクライアントコンポーネントである。

実装は、CDMの実装を分離する場合もあれば分離しない場合もあり、またそれらを ユーザーエージェントとは別個のものとして扱う場合もある。これはAPIおよびアプリケーションに対して透過的である。

キーシステム

キーシステムは、復号メカニズムおよび/またはコンテンツ保護提供者を表す汎用語である。 キーシステム文字列は、キーシステムを一意に識別する。これらは、ユーザーエージェントが CDMを選択し、キー関連イベントの発生元を識別するために使用される。 ユーザーエージェントは共通 キーシステムをサポートしなければならない(MUST)。ユーザーエージェントは、 対応するキーシステム文字列を持つ追加のCDMを提供してもよい(MAY)。

キーシステム文字列は常に逆ドメイン名である。キーシステム文字列は 大文字小文字を区別して比較される。CDMは、単純な小文字の ASCIIキーシステム文字列を使用することが推奨される(RECOMMENDED)。

例えば、"com.example.somesystem"。

あるシステム(例の "somesystem")内では、サブシステムをキーシステム提供者の判断により 定義できる。例えば、"com.example.somesystem.1" や "com.example.somesystem.1_5"。キーシステム提供者は、これらが比較および発見に使用されることを 念頭に置くべきであり、比較しやすく、構造は適度に単純なままであるべきである。

キーセッション

キーセッション、または単にセッションは、 CDMとのメッセージ交換のためのコンテキストを提供し、 その結果としてキーがCDMで利用可能になる。セッションは MediaKeySession オブジェクトとして具現化される。 各キーセッションは、 generateRequest() 呼び出しで提供される初期化データの単一のインスタンスに関連付けられる。

各キーセッションは単一の MediaKeys オブジェクトに関連付けられ、 その MediaKeys オブジェクトに関連付けられた メディア要素だけが、セッションに関連付けられたキーにアクセスできる。他の MediaKeys オブジェクト、CDM インスタンス、およびメディア要素は、キーセッションにアクセスしたり、 そのキーを使用したりしてはならない(MUST NOT)。キーセッションおよびそれに含まれるキーは、 セッションが閉じられると、復号に使用可能ではなくなる。 これには MediaKeySession オブジェクトが 破棄された場合も含まれる。

明示的に保存されていない、キーセッションに関連付けられたすべてのライセンスおよびキーは、 キーセッションが閉じられたときに破棄されなければならない(MUST)。

キーIDは、セッション内で一意でなければならない (MUST)。

セッションID

セッションIDは、CDMにより生成される一意な文字列識別子であり、 アプリケーションが MediaKeySession オブジェクトを識別するために使用できる。

新しいセッションIDは、ユーザーエージェントとCDMが 新しいセッションの作成に成功するたびに生成される。

各セッションIDは、それが作成された閲覧コンテキスト内で一意であるものとする (SHALL)。 永続セッションタイプか? アルゴリズムが true を返すセッションタイプについては、セッションIDは時間を通じて オリジン内で一意でなければならず (MUST)、閲覧セッションをまたぐ場合も含まれる。

基礎となるコンテンツ保護プロトコルは、必ずしもセッションIDをサポートする必要はない。

キー

特に明記されていない限り、キーとは メディアデータ内の ブロックを復号するために使用できる復号キーを指す。そのような各キーは キーIDによって一意に識別される。キーは、それを セッションを通じて CDMへ提供する、そのセッションに関連付けられる。(同じキーが複数のセッションに存在する場合がある。) そのようなキーは、update() 呼び出しを介してのみ CDMに提供されなければならない(MUST)。 (保存済みセッションデータの一部として、後に load() により読み込まれてもよい。)

ベストプラクティス 1: 暗号化メディアを パッケージ化する際には、意味のある差異があるポリシーの適用を必要とする ストリームの各集合を、個別のキー(およびキー ID)で暗号化する。

たとえば、2 つの映像解像度の間でポリシーが異なる場合、 ストリームの各集合は個別のキーで暗号化され、それによりポリシーを 独立して適用できる。同様に、音声ストリームと映像ストリームは、 それらのポリシーが異なる場合、個別のキーを使用する。 ポリシーグループ間でキーを共有すると独立した適用が妨げられるため、 ポリシーグループごとに個別のキーを用いることが、クライアント間での 適用と互換性を確保する唯一の方法である。

復号に使用可能

CDM が、そのキーが現在 1 つ以上の メディアデータのブロックを復号するために使用可能であると 確信している場合、キーは復号に使用可能であるとみなされる。

注記

たとえば、ライセンスの有効期限が切れている場合、キーは復号に使用可能ではない。その ライセンスの有効期限が切れていない場合でも、その使用に関する他の条件(たとえば、 出力保護)が現在満たされていない場合、キーは復号に使用可能ではない。

キー ID

キーは、オクテット列であり、そのキーを一意に 識別するキー ID に関連付けられる。コンテナーは、メディアデータ内のブロック またはブロック集合を復号できるキーの ID を指定する。初期化データは、メディアデータを復号するために必要なキーを識別するために、 キー ID を含んでもよい。 ただし、初期化データが、メディアデータまたはメディア リソースで使用されるキー ID のいずれか、またはすべてを含むという要件はない。ライセンスCDM に提供され、各キーを キー ID に関連付けるため、 CDM はメディア データの暗号化されたブロックを復号するときに適切なキーを選択できる。

既知のキー

CDM による セッションの実装が、そのキーについての何らかの情報、具体的には キー IDを含む場合、実際のキーが使用可能かどうか、またはその値が知られているかどうかにかかわらず、 そのキーはセッションにとって既知であるとみなされる。既知のキーは keyStatuses 属性を通じて公開される。

キーは、有効期限切れなどにより使用不能になった後、または削除されたものの ライセンス破棄の記録が 利用可能である場合でも、既知であるとみなされる。キーが未知になるのは、セッションから明示的に削除され、 あらゆるライセンス解放メッセージが確認された場合に限られる。

注記

たとえば、update() 呼び出しが、 そのキーを含まず、かつそのキーを以前に含んでいたライセンスを 置き換える指示を含む新しいライセンスを提供した場合、キーは未知になる可能性がある。

ライセンス

ライセンスはキーシステム固有の状態情報であり、1 つ以上のキー (それぞれがキー IDに関連付けられる)と、場合によってはキーの 使用に関するその他の情報を含む。

初期化データ
ベストプラクティス 2: 初期化データを 生成する際には、コンテンツを復号するために必要な各 キーを一意に識別する。

キーシステムは通常、ライセンス要求メッセージを構築できるようになる前に、 復号対象のストリームに関する情報を含む初期化データのブロックを 必要とする。このブロックは単純なキーまたはコンテンツ ID である場合もあれば、 そのような情報を含むより複雑な構造である場合もある。アプリケーションは、 アプリケーション固有の何らかの方法、またはメディアデータから初期化データを取得する。

初期化データは、CDM がライセンス要求を生成するために使用する、 コンテナー固有データの総称である。

初期化データの形式はコンテナーの種類に依存し、 コンテナーは複数の初期化データ形式をサポートしてもよい初期化データ型は、付随する初期化データの形式を示す文字列である。 初期化データ型文字列は常に大文字小文字を区別して照合される。 初期化データ型文字列は小文字の ASCII 文字列であることが推奨される

Encrypted Media Extensions Initialization Data Format Registry は、初期化データ型 文字列から各形式の仕様への対応を提供する。

ユーザーエージェントがメディアデータ内で初期化データに遭遇した場合、 その初期化データを、initData 属性において、encrypted イベントでアプリケーションに提供する。 ユーザーエージェントは、初期化データを保存してはならず、それに遭遇した時点でその 内容を使用してはならない。アプリケーションは、 初期化データを、 CDMgenerateRequest() を介して提供する。 ユーザーエージェントは、他の手段によって初期化データCDM に提供してはならない

初期化データは、ストリームの所与の集合またはメディア データに対して固定値でなければならない。それは、ストリームの所与の集合またはメディアデータを再生するために必要なキーに関連する情報のみを 含まなければならない。それは、アプリケーションデータ、クライアント固有データ、ユーザー固有 データ、または実行可能コードを含んではならない

初期化データは、キーシステム固有のデータまたは値を含むべきではない。 実装は、サポートする各初期化データ型について、 [EME-INITDATA-REGISTRY] で定義される共通形式をサポートしなければならない

注記

独自形式/内容の使用は推奨されず、 独自形式のみをサポートまたは使用することは強く推奨されない。独自形式は、 共通形式をサポートしない既存のコンテンツまたは既存のクライアントデバイスでのみ 使用されるべきである。

関連付け可能な値

2 つ以上の識別子またはその他の値は、それらが同一である または妥当な時間と労力で相関付けまたは関連付けることが可能である場合、 関連付け可能であるという。そうでない場合、それらの値は関連付け不可能である。

注記

たとえば、次の方法で作成された値は関連付け可能である:

  • 自明に逆変換可能なハッシュ関数を使用する。

  • 接頭辞またはその他の部分集合を共有する

  • ランダム値 N を N+10 に置き換える

  • オリジンを固定値と XOR する(自明に逆変換可能であるため)

対照的に、完全に無関係であるか、暗号学的に区別される 2 つの値、 たとえば暗号学的に強力な非可逆ハッシュ関数によるものは、 関連付け不可能である

2 つ以上の識別子またはその他の値は、参照されるエンティティまたはエンティティ集合が、 追加のエンティティの参加なしに、妥当な時間と労力でそれらを相関付けまたは関連付けることが 可能である場合、エンティティによって 関連付け可能であるという。そうでない場合、それらの値はエンティティによって 関連付け不可能である。

2 つ以上の識別子またはその他の値は、それらが アプリケーションによって関連付け不可能 であるというのは、それらがエンティティによって関連付け不可能であり、そのエンティティが、 アプリケーション、他のすべてのアプリケーション、およびそれらが使用する、または通信するサーバーなどの その他のエンティティを含む集合である場合である。そうでない場合、それらの値は アプリケーションによって関連付け可能とみなされ、これは禁止される。

特徴的な値

特徴的な値とは、大きなユーザー集団またはクライアントデバイス集団にまたがって共有されて いない値、データ片、データ片を保持していることによる含意、または観測可能な動作もしくはタイミングである。 特徴的な値はメモリ内に存在してもよく、永続化されてもよい。

注記

特徴的な値の例には、以下を含むがこれらに限定されない:

注記

特徴的な値は通常、ユーザーまたはクライアントデバイスに一意であるが、値が特徴的であるために 厳密に一意である必要はない。たとえば、少数のユーザー間で共有される値であっても、 特徴的である可能性がある。

永続的識別子

永続的識別子とは、何らかの形で消去不能である、またはユーザーが削除、リセット、変更することが 自明ではない値、データ片、データ片を保持していることによる含意、または観測可能な動作もしくはタイミングである。 これには、以下を含むがこれらに限定されない:

  • ハードウェアまたはハードウェアベースの識別子

  • 工場でハードウェアデバイスにプロビジョニングされた値

  • オペレーティングシステムのインストールインスタンスに関連付けられる、またはそこから派生する値

  • ユーザーエージェントのインストールインスタンスに関連付けられる、またはそこから派生する値

  • CDM またはその他のソフトウェア コンポーネントに関連付けられる、またはそこから派生する値

  • クライアント上で生成された場合であっても、設定ファイルまたは類似の半永続的データ内の値

  • クライアントまたはその他のユーザーアカウント値

特徴的な永続的 識別子とは、永続的識別子であり、 特徴的なものである。

クライアントの外部に公開される場合、特徴的な永続的識別子およびそれらから派生する、またはそれらに 関連する値は暗号化されなければならない。 特徴的な永続的識別子は、暗号化された形であっても、アプリケーションに公開されては ならない

注記

特徴的な永続的識別子は通常、ユーザーまたはクライアント デバイスに一意であるが、特徴的であるために厳密に一意である必要はない。 たとえば、少数のユーザー間で共有される特徴的な永続的識別子であっても、 特徴的である可能性がある。

注記

特徴的な永続的識別子は、特徴的な識別子では ない。なぜなら、それは(この仕様の範囲内で)派生または生成されるものではないからである。

注記

distinctiveIdentifier は、特徴的な 永続的識別子を使用できるかどうかを制御する。具体的には、特徴的な永続的識別子は、 MediaKeySystemAccess の メンバーであり、MediaKeys オブジェクトの作成に使用される distinctiveIdentifier メンバーの値が "required" である場合にのみ使用できる。

特徴的な識別子
注記

特徴的な識別子とは、不透明または暗号化された形を含む値であり、 クライアント外部のいずれかのエンティティが、ユーザーがウェブプラットフォーム上で 期待し得る範囲(たとえば、Cookie やその他のサイトデータ)を超えて値を相関付けまたは関連付けることが 可能であるものである。たとえば、アプリケーション以外のエンティティによって、a) オリジン間、 b) 閲覧プロファイル間、または c) 閲覧セッション間で関連付け可能な値であり、 ユーザーが閲覧データを消去してプライバシーを保護しようとした後であってもそうであるもの、 またはユーザーがそのような関連付けを断ち切ることが容易ではない値である。特に、 個別化要求に共通の値が含まれていたため、または個別化要求で提供された値が 閲覧データを消去しようとした後であってもそのようなサーバーによって関連付け可能であるために、 個別化 サーバーなどの中央サーバーが、オリジン間で値を関連付けることが可能である場合、 その値は特徴的な識別子である。これの考えられる原因には、個別化プロセスにおける 特徴的な 永続的識別子の使用が含まれる。

アプリケーションに公開される特徴的な識別子は、暗号化された形であっても、 識別子 要件の対象となり、これには 暗号化されること、 オリジンおよびプロファイルごとに 一意であること、および 消去可能であることが含まれる。

特徴的な識別子のインスタンス化または使用は、この仕様で定義される API の アプリケーションによる使用によって引き起こされるが、その識別子がアプリケーションに 提供される必要はなく、特徴的な識別子に関する条件を引き起こし得る。 (特徴的な永続的 識別子は、不透明または暗号化された形であっても、 アプリケーションに提供されない。)

注記

distinctiveIdentifier は、特徴的な 識別子を使用できるかどうかを制御する。具体的には、特徴的な識別子は、 MediaKeySystemAccess の メンバーであり、MediaKeys オブジェクトの作成に使用される distinctiveIdentifier メンバーの値が "required" である場合にのみ使用できる。

特徴的な識別子とは、以下のすべての基準を満たす、値、データ片、データ片を保持していることによる 含意、または観測可能な動作もしくはタイミングである:

  • それは特徴的である。

    注記

    特徴的な識別子は通常、ユーザーまたはクライアントデバイスに一意であるが、 識別子が特徴的であるために厳密に一意である必要はない。たとえば、 少数のユーザー間で共有される識別子であっても、特徴的である可能性がある。

  • それ、その情報、またはそれから派生する、もしくはそれに関連する値が、 暗号化された形であっても、クライアントの外部に公開される。これには、 アプリケーションおよび/またはライセンス、個別化、 またはその他のサーバーに提供することを含むが、これに限定されない。

  • それは、次のプロパティの 1 つ以上を持つ:

    注記

    アプリケーションに公開される値について規範的に禁止される、懸念のあるその他のプロパティには、 以下が含まれる:

    そのような規範的に禁止される値の例には、以下を含むがこれらに限定されない:

    • すべてのオリジンに使用される単一のハードウェアベースの値。

    • すべてのオリジンに使用される単一のランダムベースの値。

    • 個別化プロセスから取得され、 すべてのオリジンに使用される単一の値。

    • 上記の値の全部または一部を含む値。

    • 複数の、しかしすべてではないオリジンに使用される単一の値。

    • ドメイン上のすべてのオリジンに使用される単一の値。(識別子は オリジンごとでなければならない。)

    • 事前にプロビジョニングされたオリジン固有の値。

    • 自明に逆変換可能な手段によって生成された値。したがって、クライアント上で生成されたか、 個別化プロセスを伴うかにかかわらず、 それらはアプリケーションによって関連付け可能である。 たとえば、オリジンの(一部)を固定値と XOR する、またはその他の形で組み込むこと。

注記

特徴的な識別子は通常、それらを生成したエンティティによって関連付け可能 であるが、アプリケーションによって関連付け不可能でなければならない。 つまり、そのような相関付けまたは関連付けは、特徴的な識別子の値を元々生成したエンティティ、 たとえば個別化サーバーによってのみ可能である。 特徴的な永続的 識別子にアクセスできるエンティティは、 この能力をアプリケーションに公開してはならない。なぜなら、 これにより結果として生じる特徴的な識別子がアプリケーションによって関連付け可能に なるためである。また、そのような相関付けを他のエンティティまたは第三者に公開しないよう 注意を払うべきである。

注記

特徴的な識別子の例には、以下を含むがこれらに限定されない:

  • キー要求に含まれる一連のバイトであって、他のクライアントデバイスによって含まれる一連の バイトとは異なり、特徴的な永続的 識別子を使用して直接または間接的に取得された、またはそれに基づくもの。

  • キー要求に含まれる公開鍵であって、他のクライアントデバイスによる要求に含まれる公開鍵とは 異なり、特徴的な永続的 識別子を使用して直接または間接的に取得された、またはそれに基づくもの。

  • 他のクライアントデバイスが持たない秘密鍵の保持の証明(たとえば、何らかのデータに署名することによるもの)であって、 特徴的な永続的 識別子を使用して直接または間接的に取得された、またはそれに基づくもの。

  • そのようなキーの識別子。

  • 最初の値が直接公開されていないにもかかわらず、公開される別の値を派生するために 使用されるそのような値。

  • 別の特徴的な識別子から派生した値。

  • 個別化サーバーなどに、 特徴的な永続的 識別子とともに報告されたランダム値、または 特徴的な永続的 識別子を提供した後にそのようなサーバーから提供されたランダム値。

  • 工場でハードウェアデバイスにプロビジョニングされた一意の値から派生した値。

  • 工場でハードウェアデバイス内にある一意のハードウェア値(たとえば、MAC アドレスまたはシリアル番号) またはソフトウェア値(たとえば、オペレーティングシステムのインストールインスタンスまたは オペレーティングシステムのユーザーアカウント名)から派生した値。

  • CDM バイナリまたは CDM によって使用されるその他のファイルに埋め込まれた一意の値から派生した値。

特徴的な識別子ではないものの例:

  • インストールベースが大きい場合に、所与の CDM バージョンのすべてのコピーで共有される公開鍵。

  • 一意であるが 1 つのセッションでのみ使用される nonce または一時鍵。

  • 個別化 または類似のものを含め、派生または類似の方法であっても、クライアント外部に公開されない値。

  • たとえば映像パイプラインと CDM との間の証明に使用されるデバイス固有の鍵であって、 CDM が これらの証明をアプリケーションへさらに流出させず、代わりに特徴的な識別子を構成しない鍵を 使用して自ら新しい証明を行う場合。

  • Cookie などの閲覧データとともに完全に消去/消去可能な値であって、 その後、中央サーバー、たとえば個別化 サーバーによってさえも関連付け不可能] な値 (単にアプリケーションによって 関連付け不可能であるだけではない)に置き換えられ、かつ以下の 1 つ以上を満たすもの:

    • その値の生成に特徴的な 永続的識別子または特徴的な識別子が 関与していない。

    • それはシステムからの入力なしに生成されたランダム値である。

    • それは、別の特徴的な識別子の使用または知識なしにサーバーによって提供された値である。

特徴的な識別子および 特徴的な永続的 識別子の使用

実装、構成、インスタンス、またはオブジェクトが、その存続期間中または関連するそのような エンティティの存続期間中の任意の時点で、1 つ以上の特徴的な識別子、 それらに関する情報、またはそれらから派生する、もしくはそれらに関連する値を、 暗号化された形であってもクライアントの外部に公開する場合、その実装、構成、インスタンス、 またはオブジェクトは特徴的な 識別子を使用する。これには、そのような値を アプリケーションおよび/またはライセンス、個別化、またはその他の サーバーに提供することを含むが、これに限定されない。

実装、構成、インスタンス、またはオブジェクトが、その存続期間中または関連するそのような エンティティの存続期間中の任意の時点で、1 つ以上の 特徴的な永続的 識別子、それらに関する情報、またはそれらから派生する、 もしくはそれらに関連する値を、暗号化された形であってもクライアントの外部に公開する場合、 その実装、構成、インスタンス、またはオブジェクトは特徴的な 永続的識別子を使用する。これには、そのような値を 個別化サーバーに提供することを含むが、 これに限定されない。そのような値はアプリケーションに提供されてはならない

実装、構成、インスタンス、またはオブジェクトは、それが 特徴的な識別子を使用する、および/または 特徴的な 永続的識別子を使用する場合、 特徴的な識別子または特徴的な永続的識別子を使用する

注記

distinctiveIdentifier は、特徴的な識別子 および特徴的な 永続的識別子を使用できるかどうかを制御する。具体的には、そのような 識別子は、MediaKeySystemAccess の メンバーであり、MediaKeys オブジェクトの作成に使用される distinctiveIdentifier メンバーの値が "required" である場合にのみ使用できる。

クロスオリジンの制限

再生中、埋め込まれたメディアデータは埋め込み元のオリジン内のスクリプトに公開される。 API が初期化データencrypted イベントで提供するためには、 メディア データは、埋め込みページと CORS 同一オリジン でなければならないメディア データが埋め込み文書とクロスオリジンである場合、著者は crossOrigin 属性をHTMLMediaElement 上で使用し、かつメディアデータ応答上の CORS ヘッダーを使用して、 それを CORS 同一オリジンにするべきである。

混在 コンテンツの制限

再生中、埋め込まれたメディアデータは埋め込み元のオリジン内のスクリプトに公開される。 API が初期化データencrypted イベントで提供するためには、 メディア データ混在コンテンツ [MIXED-CONTENT] であってはならない

時刻

時刻は、 ECMAScript Language Specification に表されるものと等価でなければならない

そのような時刻が存在しない場合、または時刻が不定である場合、時刻は NaN になる。 それは決して Infinity の値を持つべきではない。

注記

時刻は一般にミリ秒精度のある時点を表す。ただし、それだけでは十分な定義ではない。 参照される Time Values and Time Range は、その他の重要な要件を追加している。

有効期限時刻

キーが復号に使用可能でなくなる時点より後の 時刻

閲覧プロファイル

所与のマシン上のユーザーエージェントは、アプリケーションに可視な状態およびデータに関して 独立して振る舞うことが期待される、さまざまな異なるコンテキスト、モード、または一時的な状態での 実行をサポートする場合がある。特に、すべての保存データは独立していることが期待される。 この仕様では、そのような独立したコンテキストまたはモードを「閲覧プロファイル」と呼ぶ。

注記

そのような独立したコンテキストの例には、ユーザーエージェントが異なるオペレーティングシステムの ユーザーアカウントで実行されている場合、またはユーザーエージェントが単一のアカウントに対して 複数の独立したプロファイルを定義する機能を提供する場合が含まれる。

3. キーシステムへのアクセスの取得

このセクションは、キーシステムへのアクセスを 取得するための仕組みを定義する。要求に機能を含めることで、機能検出も可能になる。

アルゴリズムの手順は、promiseを拒否するときには常に中止される。

3.1 Permissions Policy 統合

requestMediaKeySystemAccess() は、文字列 encrypted-media により識別されるポリシー制御 機能である。 その既定の 許可リスト'self' である [PERMISSIONS-POLICY]。

3.3 MediaKeySystemConfiguration 辞書

WebIDLenum MediaKeysRequirement {
  "required",
  "optional",
  "not-allowed"
};

MediaKeysRequirement 列挙型は次のように定義される:

列挙型の説明
required
requestMediaKeySystemAccess() の呼び出しで使用される場合
返されるオブジェクトは、この機能をサポートしなければならない(MUST)。
MediaKeySystemAccess オブジェクトにより返される場合
オブジェクトにより作成されるCDM インスタンスは、この機能を使用してもよい (MAY)。
optional
requestMediaKeySystemAccess() の呼び出しで使用される場合
返されるオブジェクトは、この機能をサポートし使用してもよい(MAY)。
MediaKeySystemAccess オブジェクトにより返される場合
この値は、そのようなオブジェクトに存在できず、存在してはならない (MUST NOT)。
not-allowed
requestMediaKeySystemAccess() の呼び出しで使用される場合
返されるオブジェクトは、この機能を使用せずに機能しなければならず(MUST)、 いかなる時点でもそれを使用してはならない(MUST NOT)。
MediaKeySystemAccess オブジェクトにより返される場合
オブジェクトにより作成されるCDM インスタンスは、この機能を使用してはならない (MUST NOT)。
WebIDLdictionary MediaKeySystemConfiguration {
  DOMString                               label = "";
  sequence<DOMString>                     initDataTypes = [];
  sequence<MediaKeySystemMediaCapability> audioCapabilities = [];
  sequence<MediaKeySystemMediaCapability> videoCapabilities = [];
  MediaKeysRequirement                    distinctiveIdentifier = "optional";
  MediaKeysRequirement                    persistentState = "optional";
  sequence<DOMString>                     sessionTypes;
};

辞書 MediaKeySystemConfiguration は 次のメンバーを含む。

label 型は DOMString、既定値は ""
MediaKeySystemConfiguration に 保持される任意のラベルであり、これは MediaKeySystemAccessgetConfiguration() メソッドから返されるものである。
initDataTypes 型は sequence<DOMString>、 既定値は []
サポートされる初期化データタイプ 名の一覧。このオブジェクトの初期化データタイプ 機能は、一覧が空であるか、(アルゴリズムにより決定されるように)すべての他のメンバーと共に サポートされる1つ以上の値を含む場合にサポートされるとみなされる。 シーケンス内の値は空文字列であってはならない(MUST)。
audioCapabilities 型は sequence<MediaKeySystemMediaCapability>、 既定値は []
サポートされる音声タイプと機能の組の一覧。このオブジェクトの音声機能は、 一覧が空であるか、(アルゴリズムにより決定されるように)すべての他のメンバーと共に サポートされる1つ以上の値を含む場合にサポートされるとみなされる。値の間に 競合がある場合、より前の値が選択される。空の一覧は、 音声機能がサポートされないことを示す。この場合、 videoCapabilities 要素は空であってはならない。
videoCapabilities 型は sequence<MediaKeySystemMediaCapability>、 既定値は []
サポートされる動画タイプと機能の組の一覧。このオブジェクトの動画機能は、 一覧が空であるか、(アルゴリズムにより決定されるように)すべての他のメンバーと共に サポートされる1つ以上の値を含む場合にサポートされるとみなされる。値の間に 競合がある場合、より前の値が選択される。空の一覧は、 動画機能がサポートされないことを示す。この場合、 audioCapabilities 要素は空であってはならない。
distinctiveIdentifier 型は MediaKeysRequirement、 既定値は "optional"
特徴的な識別子 の使用が必要かどうか。

このメンバーが "not-allowed" である場合、 実装は、この構成から作成された任意のオブジェクトに関連付けられた任意の操作について、 特徴的な 識別子または特徴的な永続識別子を使用してはならない(MUST NOT)。

persistentState 型は MediaKeysRequirement、既定値は "optional"
状態を永続化する能力が必要かどうか。これにはセッションデータおよびその他の 種類の状態が含まれる。

このメンバーが "not-allowed" である場合、 CDM は、このオブジェクトの Document のアプリケーションまたは オリジンに関連する いかなる状態も永続化してはならない(MUST NOT)。

このメンバーの目的上、永続状態には、キーシステム 実装により制御される永続的な一意識別子 (特徴的な 識別子)は含まれない。 distinctiveIdentifier はこの要件を独立して反映する。

永続状態がサポートされない場合、作成できるのは "temporary" セッションのみである。

"temporary" セッションでは、 状態を保存する必要性および能力は キーシステム実装固有であり、使用される機能により変わる可能性がある。

非 "temporary" セッションの 作成を意図するアプリケーションは、 requestMediaKeySystemAccess() を呼び出すとき、このメンバーを "required" に 設定すべきである。

sessionTypes 型は sequence<DOMString>
サポートされなければならない MediaKeySessionType の一覧。 すべての値が サポートされなければならない。

辞書が requestMediaKeySystemAccess() に渡されるとき、このメンバーが存在しない [Infra] 場合、 辞書はこのメンバーが [ "temporary" ] に設定されているかのように扱われる。

実装はこの辞書にメンバーを追加すべきではない(SHOULD NOT)。 メンバーが追加される場合、 それらは MediaKeysRequirement 型でなければならず (MUST)、かつ、最も広い アプリケーションとクライアントの組み合わせをサポートするために、既定値を "optional" にすることが 推奨される(RECOMMENDED)。

ユーザーエージェント実装により認識されない辞書メンバーは、 [WEBIDL] に従って無視され、requestMediaKeySystemAccess() アルゴリズムでは考慮されない。アプリケーションが非標準の辞書メンバーを使用する場合、 そのような辞書メンバーを含む構成がユーザーエージェント実装により拒否されることに 依存してはならない(MUST NOT)。

この辞書は、状態またはデータを CDM に渡すために使用してはならない(MUST NOT)。

3.4 MediaKeySystemMediaCapability 辞書

WebIDLdictionary MediaKeySystemMediaCapability {
  DOMString contentType = "";
  DOMString? encryptionScheme = null;
  DOMString robustness = "";
};

3.4.1 辞書 MediaKeySystemMediaCapability メンバー

contentType 型は DOMString、既定値は ""

メディアリソースMIMEタイプ

encryptionScheme 型は DOMString、既定値は null

コンテンツタイプに関連付けられた暗号化方式。null である、または 存在しない値は、特定の暗号化方式がアプリケーションにより要求されていないため、 どの暗号化方式でも許容されることをユーザーエージェントに示す。

注記

空文字列は null または存在しないこととは異なるため、 認識されない暗号化方式として扱われる。

注記

encryptionScheme のよく知られた値は次のとおりである:

  • cenc: [CENC] の 4.2a 節で定義される "cenc" モード。AES-CTR モードによる完全サンプルおよび映像 NAL サブサンプル暗号化。
  • cbcs: [CENC] の 4.2d 節で定義される "cbcs" モード。AES-CBC モードによる部分的な映像 NAL パターン 暗号化。映像については、仕様はさまざまな暗号化パターンを許容している。
  • cbcs-1-9: "cbcs" モードと同じだが、[CENC] の 10.4.2 節で推奨される、映像用の 1:9 という特定の encrypt:skip パターンを伴う。
robustness 型は DOMString、既定値は ""

コンテンツ型に関連付けられた堅牢性レベル。空文字列は、 そのコンテンツ型を復号およびデコードする任意の能力が許容されることを示す。 実装は、CDM を、MediaKeySystemAccess オブジェクトの 構成で指定された少なくとも堅牢性レベルをサポートするように構成しなければならない (MUST)。そのオブジェクトは MediaKeys オブジェクトを 作成するために使用されたものである。

このオブジェクトにより表される機能がサポートされるとみなされるためには、 contentType は 空文字列であってはならず(MUST NOT)、かつ、すべてのコーデックを含むその値全体が、 robustness と共に サポートされなければならない(MUST)。

注記

コーデック集合のいずれかが受け入れ可能である場合は、各コーデックに対して この辞書の別個のインスタンスを使用する。

ベストプラクティス 3: MediaKeySystemMediaCapabilityrequestMediaKeySystemAccess() に渡す際には、 コンテナーが規範的にそれらを含意していない限り、MIME 型内に コーデックおよびコーデック制約を指定し(たとえば [RFC6381] に従う)、 encryptionScheme は null のデフォルト値に依存するのではなく、 特定の値に設定する。

異なる暗号化方式は一般に互いに互換性がない。null のデフォルト値と、 null を「任意」と解釈することは、認識していないアプリケーションの後方互換性と、 古いユーザーエージェント向けのポリフィルへの道筋を提供する。

4. MediaKeySystemAccess インターフェイス

MediaKeySystemAccess オブジェクトは、キーシステムへのアクセスを提供する。

WebIDL[Exposed=Window, SecureContext] interface MediaKeySystemAccess {
  readonly attribute DOMString keySystem;
  MediaKeySystemConfiguration  getConfiguration ();
  Promise<MediaKeys>           createMediaKeys ();
};

4.1 属性

keySystem 型は DOMString, readonly
使用されているキーシステムを識別する。

4.2 メソッド

getConfiguration()

requestMediaKeySystemAccess() アルゴリズムにより選択された、サポートされる構成オプションの組み合わせを返す。

返されるオブジェクトは、このオブジェクトで解決されたpromiseを返した requestMediaKeySystemAccess() 呼び出しに渡された、最初に満たされた MediaKeySystemConfiguration 構成の非厳密な部分集合(および暗黙の既定値)である。 その単一の構成で指定されていない機能の値(暗黙の既定値を除く)は含まれず、 したがってキーシステム実装の すべての機能を反映しない場合がある。構成内のすべての値は任意の組み合わせで使用できる。 型が MediaKeysRequirement であるメンバーは、 その機能がいずれかの組み合わせで必要かどうかを反映する。 それらは値 "optional" を持たない。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの configuration 値を返す。

    注記

    これにより、このメソッドが呼び出されるたびに、 configuration から新しいオブジェクトが作成され、初期化される。

    注記

    encryptionScheme がアプリケーションによって与えられていなかった場合でも、 累積された configuration は、特定の値を指定せずに ポリフィルがそのフィールドに対するユーザーエージェントのサポートを 検出できるように、値が null である encryptionScheme フィールドを依然として含まなければならない

createMediaKeys()

keySystem 用の新しい MediaKeys オブジェクトを作成する。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. promise を新しいpromiseとする。

  2. 次の手順を並列に実行する。

    1. configuration を、このオブジェクトの configuration 値の値とする。

    2. configurationdistinctiveIdentifier メンバーの値が "required" である場合、use distinctive identifiertrue とし、 それ以外の場合は false とする。

    3. configurationpersistentState メンバーの値が "required" である場合、persistent state allowedtrue とし、 それ以外の場合は false とする。

    4. 必要であれば、このオブジェクトの cdm implementation 値により表される キーシステム実装を読み込み、初期化する。

    5. instance を、このオブジェクトの cdm implementation 値により表されるキーシステム実装の新しいインスタンスとする。

    6. configuration を用いて、キーシステム機能を有効化、無効化、かつ/または選択するように instance を初期化する。

    7. use distinctive identifierfalse である場合、 instance特徴的な 識別子および特徴的な永続識別子を使用することを防止する。

    8. persistent state allowedfalse である場合、 instance が、このオブジェクトの Document のアプリケーションまたは オリジンに関連する いかなる状態も永続化することを防止する。

    9. 前述の手順のいずれかが失敗した場合、適切なエラー 名を名前に持つ新しい DOMExceptionpromise を拒否する。

    10. media keys を新しい MediaKeys オブジェクトとし、 次のように初期化する。

      1. use distinctive identifier 値を use distinctive identifier とする。

      2. persistent state allowed 値を persistent state allowed とする。

      3. supported session types 値を、 configurationsessionTypes メンバーの値とする。

      4. cdm implementation 値をこのオブジェクトの cdm implementation 値とする。

      5. cdm instance 値を instance とする。

    11. promisemedia keys で解決する。

  3. promise を返す。

5. MediaKeys インターフェイス

MediaKeys オブジェクトは、関連付けられた HTMLMediaElement が再生中にメディアデータの復号に 使用できるキーの集合を表す。また、 CDM インスタンスも表す。

MediaKeys オブジェクトは、アクセス不能になったときに ユーザーエージェントにより破棄されることがある。

例えば、スクリプト参照がなく、接続されたメディア要素もない場合。

promiseを返すメソッドについては、すべてのエラーは返されたPromiseを拒否することで非同期に報告される。 これには [WEBIDL] 型マッピングエラーも含まれる。

アルゴリズムの手順は、promiseを拒否するときには常に中止される。

WebIDLenum MediaKeySessionType {
  "temporary",
  "persistent-license"
};

MediaKeySessionType 列挙型は次のように定義される:

列挙型の説明
temporary

ライセンス、キー、およびセッションに関する記録またはデータが永続化されないセッション。

アプリケーションはそのようなストレージの管理を気にする必要がない。 このセッションタイプのサポートは必須である(REQUIRED)。

persistent-license

ライセンス(および場合によってはセッションに関する他のデータ)が永続化されるセッション。 ライセンスおよびそれが含むキーが破棄されるとき、 ライセンス破棄の記録は 永続化されなければならない(SHALL)。ライセンス 破棄の記録は、ライセンスおよびそれが含むキーがクライアントにより もはや使用可能でないことを示す、キーシステム固有の証明である。 このセッションタイプのサポートは任意である(OPTIONAL)。

このタイプのセッションは、このオブジェクトを作成した MediaKeySystemAccess オブジェクトに 関連付けられた構成の persistentState 値が "required" である場合にのみ 作成できる。update() が正常に呼び出されると、 セッションはそのセッションIDを介して読み込み可能でなければならない (MUST)。message 型 "license-release" で、ライセンス破棄の記録を含むものは、 remove() が呼び出されたときから、 その記録が update() に渡された応答により 確認応答されるまで生成される。

アプリケーションは、そのようなセッションのために永続化されたデータが、 アプリケーションで不要になったときに削除されるようにする責任を負う。 セッションストレージと永続性を参照。

WebIDL[Exposed=Window, SecureContext] interface MediaKeys {
    MediaKeySession createSession (optional MediaKeySessionType sessionType = "temporary");
    Promise<MediaKeyStatus> getStatusForPolicy (optional MediaKeysPolicy policy = {});
    Promise<boolean> setServerCertificate (BufferSource serverCertificate);
};

5.1 メソッド

createSession()

新しい MediaKeySession オブジェクトを返す。

sessionType パラメーターは、返されるオブジェクトの動作に影響する。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの supported session types 値が sessionType を含まない場合、throw [WEBIDL] で NotSupportedError を投げる。

    永続セッションタイプか? アルゴリズムが true を返す sessionType 値は、 このオブジェクトの persistent state allowed 値が false である場合、失敗する。

  2. 実装が現在の状態で MediaKeySession 操作を サポートしない場合、throw [WEBIDL] で InvalidStateError を投げる。

    一部の実装は、この MediaKeys オブジェクトが setMediaKeys() を用いてメディア要素に関連付けられるまで、 MediaKeySession アルゴリズムを 実行できない。この手順により、アプリケーションはそのような操作を試みる前に、 この一般的でない動作を検出できる。

  3. session を新しい MediaKeySession オブジェクトとし、 次のように初期化する。

    1. sessionId 属性を空文字列とする。

    2. expiration 属性を NaN とする。

    3. closed 属性を 新しいpromiseとする。

    4. key status を新しい空の MediaKeyStatusMap オブジェクトとし、次のように初期化する。

      1. size 属性を 0 とする。

    5. session type 値を sessionType とする。

    6. uninitialized 値を true とする。

    7. callable 値を false とする。

    8. closing or closed 値を false とする。

    9. use distinctive identifier 値を、このオブジェクトの use distinctive identifier 値とする。

    10. cdm implementation 値を、このオブジェクトの cdm implementation とする。

    11. cdm instance 値を、このオブジェクトの cdm instance とする。

  4. session を返す。

getStatusForPolicy()

与えられた MediaKeysPolicy に対する MediaKeyStatus を返す。

WebIDLdictionary MediaKeysPolicy {
    DOMString minHdcpVersion;
};

MediaKeysPolicy 辞書は、任意のプロパティのみで構成されるオブジェクトである。 各プロパティはポリシー要件を表す。すべての要件に基づいて CDM が復号済みメディアデータの提示を許可する場合、 ポリシーは満たされているという。

HDCPポリシーは minHdcpVersion により表される。 システムが指定されたHDCPバージョン以上を有効化できる場合、そのポリシーは "usable" の MediaKeyStatus になる。 [EME-HDCP-VERSION-REGISTRY] は、 minHdcpVersion 値から HDCP仕様への対応付けを提供する。

HDCPステータスの判定は、CDM が再生中にそのような制限を強制する方法と同じ方法で行われるべきである。 これにより、アプリケーション開発者は、再生を開始するために取得するコンテンツを 最適化できるよう、妥当なヒントを得ることができる。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. policy存在する 辞書メンバーがない場合、 新しく作成された TypeError で拒否された promiseを返す。
  2. promise を新しいpromiseとする。

  3. 次の手順を実行するためにタスクを キューに入れる

    1. policy の各辞書 メンバーについて、次の手順を実行する。

      1. キーが有効な MediaKeysPolicy メンバーでない、または値の型が正しくない場合、promiseTypeError で拒否し、これらの手順を中止する。

    2. policy の各辞書 メンバーについて、次の手順を実行する。

      1. CDM が、その 辞書 メンバーに対する MediaKeyStatus を判定できない場合、promiseNotSupportedError で拒否し、これらの手順を中止する。

    3. policy の各辞書 メンバーについて、次の手順を実行する。

      1. CDM が、その 辞書 メンバーについて復号済みメディアデータの提示をブロックする場合、 promise を "output-restricted" で解決し、これらの手順を中止する。

    4. promise を "usable" で解決する。

  4. promise を返す。

setServerCertificate()

ライセンスサーバーへのメッセージの暗号化に使用されるサーバー証明書を提供する。

そのような証明書を使用するキーシステムでは、アプリケーションはサーバー証明書を 明示的に設定するために setServerCertificate() を呼び出すべきである(SHOULD)。 そうしない場合、ライセンス交換が失敗することがある。

一部のキーシステムは、"message" イベントをキューに入れるアルゴリズムを介して サーバーから証明書を要求することもサポートする。しかし、 これはそのような証明書を使用するすべてのキー システムでサポートされているわけではない。

サーバー証明書の内容はキーシステム固有である。 実行可能コードを含んではならない(MUST NOT)。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの cdm implementation 値により表される キーシステム実装がサーバー証明書をサポートしない場合、 false で解決されたpromiseを返す。

  2. serverCertificate が空配列である場合、新しく作成された TypeError で拒否された promiseを返す。

  3. certificate を、 serverCertificate パラメーターの内容のコピーとする。

  4. promise を新しいpromiseとする。

  5. 次の手順を並列に実行する。

    1. sanitized certificate を、certificate の検証済みかつ/または サニタイズ済みバージョンとする。

      ユーザーエージェントは、証明書を CDM に渡す前に 徹底的に検証すべきである。これには、値が妥当な制限内にあることの確認、 無関係なデータまたはフィールドの除去、事前解析、サニタイズ、および/または 完全にサニタイズされたバージョンの生成が含まれることがある。 ユーザーエージェントは、フィールドの長さと値が妥当であることを確認すべきである。 不明なフィールドは拒否または削除されるべきである。

    2. このオブジェクトの cdm instance を使用して sanitized certificate を処理する。

    3. 前述の手順が失敗した場合、適切なエラー 名を名前に持つ新しい DOMExceptionpromise を拒否する。

    4. promisetrue で解決する。

  6. promise を返す。

5.2 アルゴリズム

5.2.1 永続セッションタイプか?

永続セッションタイプか? アルゴリズムは、指定されたセッションタイプが何らかの種類の永続化を サポートするかどうかを判断するために実行される。このアルゴリズムの実行要求には、 MediaKeySessionType 値が含まれる。

次の手順を実行する。

  1. session type を、指定された MediaKeySessionType 値とする。

  2. session type の値について、次の一覧の手順に従う。

    "temporary"
    false を返す。
    "persistent-license"
    true を返す。

5.2.2 CDM 利用不可

CDM利用不可アルゴリズムは、CDM インスタンスが利用不可になったときに、 MediaKeys オブジェクト media keys に関連付けられたすべての MediaKeySession オブジェクトを 閉じるために実行される。このアルゴリズムの実行要求には、 MediaKeySessionClosedReason 値が含まれる。

次の手順を実行する。

  1. reason を、指定された MediaKeySessionClosedReason 値とする。

  2. media keys により作成され、かつ閉じられていない各 MediaKeySession について、理由 reason でそのセッションに対して セッション閉鎖 アルゴリズムを実行するためにタスクを キューに入れる

5.3 ストレージと永続性

このセクションは、ストレージおよび永続性に関する一般的な要件を記述する。

MediaKeys オブジェクトの persistent state allowed 値が false である場合、そのオブジェクトの cdm instance は、このオブジェクトまたは これが作成する任意のセッションに対する操作の結果として、状態を永続化したり、 以前に永続化された状態にアクセスしたりしてはならない(SHALL NOT)。

MediaKeys オブジェクトの persistent state allowed 値が true である場合、そのオブジェクトの cdm instance は、このオブジェクトまたは これが作成する任意のセッションに対する操作の結果として、状態を永続化したり、 以前に永続化された状態にアクセスしたりしてもよい(MAY)。

永続化されたデータは、常に、このオブジェクトの Documentオリジンのみが アクセスできるように保存されなければならない(MUST)。 さらに、そのデータは現在の 閲覧プロファイルからのみアクセス可能でなければならない (MUST)。他の閲覧プロファイル、ユーザーエージェント、および アプリケーションは、保存されたデータにアクセスできてはならない(MUST NOT)。 ユーザーデバイスに保存される情報を参照。

永続ストレージをサポートする際の追加の考慮事項については、10. セキュリティおよび11. プライバシーを参照。

6. MediaKeySession インターフェイス

MediaKeySession オブジェクトはキーセッションを表す。

MediaKeySession オブジェクトは、そのオブジェクトの closed 属性が解決されている場合、かつ その場合に限り、閉じられている

ユーザーエージェントは、CDM状態変化の監視アルゴリズムを、 閉じられていないMediaKeySession オブジェクトについて 継続的に実行しなければならない(SHALL)。 CDM状態変化の監視アルゴリズムは、メインイベントループと 並列に実行されなければならない(MUST)が、この仕様で定義され、同じく並列に実行されるものとして 定義されている他の手続きとは並列に実行してはならない。

MediaKeySession オブジェクトは、それが 閉じられておらず、それを作成した MediaKeys オブジェクトが引き続きアクセス可能である場合、破棄されてはならず(SHALL NOT)、イベントを受け取り続けなければならない(SHALL)。 それ以外の場合、もはやアクセス可能でない MediaKeySession オブジェクトは、 それ以上のイベントを受け取ってはならず(SHALL NOT)、 破棄されてもよい(MAY)。

上記の規則は、CDM インスタンスに関連付けられたすべての MediaKeys オブジェクトおよびすべての MediaKeySession オブジェクトが破棄されるまで、 CDM インスタンスを破棄してはならないことを意味する。

MediaKeySession オブジェクトがページから アクセス不能になったときに閉じられていない場合、 CDM は、そのオブジェクトに関連付けられたキーセッションを閉じなければならない(SHALL)。

注記

キーセッションを閉じると、明示的に保存されていないライセンスおよびキーは すべて破棄される。

ベストプラクティス 4: 別の操作を行う前に キーセッションが確実に閉じられている必要がある場合は、close() を呼び出し、返された promise を待機する。 自動的なセッション閉鎖のタイミングに依存しない。

キーセッションが正確にいつ閉じられるかは、実装の詳細である。

promiseを返すメソッドについては、すべてのエラーは返されたPromiseを拒否することで非同期に報告される。 これには [WEBIDL] 型マッピングエラーも含まれる。

アルゴリズムの次の手順は、promiseを拒否するときには常に中止される。

WebIDLenum MediaKeySessionClosedReason {
  "internal-error",
  "closed-by-application",
  "release-acknowledged",
  "hardware-context-reset",
  "resource-evicted"
};

MediaKeySessionClosedReason 列挙型は次のように定義される:

列挙型の説明
internal-error セッションは、CDM 内の回復不能なエラーのため閉じられた。 これが発生した場合、アプリケーションは、この MediaKeys インスタンス上に新しいセッションを 作成してはならない(MUST NOT)。
closed-by-application セッションは、アプリケーションがセッションの close() メソッドを明示的に呼び出したため閉じられた。
release-acknowledged セッションは、CDMライセンス 破棄の記録の確認応答を受信したため閉じられた。
hardware-context-reset セッションは、CDM の元のハードウェアコンテキストが リセットされたため閉じられた。 これが発生した場合、ユーザーエージェントは、アプリケーションがこの MediaKeys インスタンス上に新しいセッションを 作成できるようにしなければならない(MUST)。

これは、デバイスの休止状態、モニター構成の変更など、多くの理由で発生し得る。 ハードウェアコンテキストリセットの正確な理由は実装依存である。

resource-evicted セッションは、他のセッションの作成を可能にするため、システムがリソースを回収する必要が あったため閉じられた。

これは、アプリケーションがデバイス固有のセッションリソース制限に達していることを 意味する。閉じられたセッションが何らかの理由でまだ必要な場合、 アプリケーション開発者は、必要なセッション数を減らすための方策、または 不要なセッションを事前に閉じる方策を検討すべきである。

WebIDL[Exposed=Window, SecureContext] interface MediaKeySession : EventTarget {
  readonly        attribute DOMString                            sessionId;
  readonly        attribute unrestricted double                  expiration;
  readonly        attribute Promise<MediaKeySessionClosedReason> closed;
  readonly        attribute MediaKeyStatusMap                    keyStatuses;
                  attribute EventHandler                         onkeystatuseschange;
                  attribute EventHandler                         onmessage;
  Promise<undefined>    generateRequest (DOMString initDataType, BufferSource initData);
  Promise<boolean> load (DOMString sessionId);
  Promise<undefined>    update (BufferSource response);
  Promise<undefined>    close ();
  Promise<undefined>    remove ();
};

6.1 属性

sessionId 型は DOMString, readonly

このオブジェクト、および関連付けられたキーまたはライセンスの セッションID

expiration 型は unrestricted double, readonly

セッション内のすべてのキーについての有効期限時刻、またはそのような 時刻が存在しない場合、あるいはライセンスが明示的に期限切れにならない場合は NaN。これは CDM によって決定される。 この値は、セッションの存続期間中に変更される可能性がある。たとえば、ある操作が ウィンドウの開始をトリガーする場合などである。

closed 型は Promise<MediaKeySessionClosedReason>, readonly

セッション閉鎖アルゴリズムの実行の結果として オブジェクトが閉じられるときに通知する。 このpromiseは履行されるだけであり、拒否されることはない。

keyStatuses 型は MediaKeyStatusMap, readonly

セッションに既知であるキー IDから、関連付けられたキーの現在のステータスへの読み取り専用マップへの参照。 各エントリーは一意なキーIDを持たなければならない(MUST)。

マップのエントリーとその値は、イベントループが回るたびに更新されることがある。 マップは決して不整合または部分的に更新された状態であってはならない (MUST NOT)が、アクセスの間にイベントループが回った場合、 そのアクセスの間で変化することがある。キーIDは、 load() または update() 呼び出しの結果として 追加されることがある。 キーIDは、既存のキーに関する知識を削除する(または既存のキー集合を新しい集合に置き換える) update() 呼び出しの結果として 削除されることがある。キー IDは、有効期限切れなどにより使用不能になったという理由で削除されてはならない (MUST NOT)。 代わりに、そのようなキーには、"expired" などの 適切なステータスが与えられなければならない(MUST)。

注記

一部の古いプラットフォームには、キー ID を公開しない キーシステム実装が含まれる場合があり、 適合するユーザーエージェント実装を提供することが不可能になる。そのような場合、 相互運用性を最大化するために、空でないリストが適切であるときは常に (たとえば、このオブジェクトによって表されるキーセッションキーを含むことができる場合)、 マップには、1 バイトのキー ID 0 と、このオブジェクトの集約された状態に 最も適した MediaKeyStatus を含む 単一のペアが設定される。

onkeystatuseschange 型は EventHandler

keystatuseschange イベントの イベントハンドラー。

onmessage 型は EventHandler

message イベントの イベントハンドラー。

6.2 メソッド

generateRequest()

initData に基づいてライセンス要求を生成する。アルゴリズムが成功し、 promiseが解決される場合、型 "license-request" または "individualization-request" のmessageが常にキューに入れられる。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの closing or closed 値が true である場合、 InvalidStateError で拒否されたpromiseを返す。

  2. このオブジェクトの uninitialized 値が false である場合、 InvalidStateError で拒否されたpromiseを返す。

  3. このオブジェクトの uninitialized 値を false とする。

  4. initDataType が空文字列である場合、新しく作成された TypeError で拒否されたpromiseを返す。

  5. initData が空配列である場合、新しく作成された TypeError で拒否されたpromiseを返す。

  6. このオブジェクトの cdm implementation 値により表される キーシステム実装が、initDataType初期化データ タイプとしてサポートしない場合、 NotSupportedError で拒否されたpromiseを返す。文字列比較は大文字小文字を区別する。

  7. init datainitData パラメーターの内容のコピーとする。

  8. session type を、このオブジェクトの session type とする。

  9. promise を新しいpromiseとする。

  10. 次の手順を並列に実行する。

    1. init datainitDataType に対して有効でない場合、 新しく作成された TypeErrorpromise を拒否する。

    2. sanitized init data を、 init data の検証済みでサニタイズ済みのバージョンとする。

      ユーザーエージェントは、初期化 データCDM に渡す前に、 徹底的に検証しなければならない(MUST)。 これには、フィールドの長さおよび値が妥当であることの確認、値が妥当な 制限内にあることの確認、および無関係な、サポートされない、または未知の データまたはフィールドの除去が含まれる。ユーザーエージェントが 初期化データを事前解析、 サニタイズ、かつ/または完全にサニタイズされたバージョンを生成することが 推奨される(RECOMMENDED)。initDataType により 指定される初期化 データ形式が複数のエントリーをサポートする場合、 ユーザーエージェントは、CDM に不要なエントリーを 削除すべきである(SHOULD)。 ユーザーエージェントは、初期化 データ内のエントリーを並べ替えてはならない(MUST NOT)。

    3. 前述の手順が失敗した場合、新しく作成された TypeErrorpromise を拒否する。

    4. sanitized init data が空である場合、 NotSupportedErrorpromise を拒否する。

    5. session id を空文字列とする。

    6. message を null とする。

    7. message type を null とする。

    8. cdm を、このオブジェクトの cdm instance 値により表される CDM インスタンスとする。

    9. cdm を使用して次の手順を実行する。

      1. sanitized init datacdm により サポートされない場合、NotSupportedErrorpromise を拒否する。

      2. session type の値について、次の一覧の手順に従う。

        "temporary"

        requested license type を、一時的で永続化不能な ライセンスとする。

        返されるライセンスは、永続化可能であってはならず、またはそれに 関連する情報の永続化を要求してはならない。

        "persistent-license"

        requested license type を永続化可能なライセンスとする。

      3. session id を一意なセッションID 文字列とする。

        session type に対して永続セッション タイプか?アルゴリズムを実行した結果が true である場合、 そのIDは、このオブジェクトの Documentオリジン 内で、Document間および閲覧セッション間を含め、時間を通じて 一意でなければならない(MUST)。

      4. sanitized init data に基づいて requested license type のライセンス要求を生成できる場合:
        1. message を、initDataType ごとに 解釈される sanitized init data に基づいて 生成された requested license type の ライセンス要求とする。

          cdm は、sanitized init data を介して 提供されていない、メディア データを含む、ストリーム固有のデータを一切使用してはならない (MUST NOT)。

          cdm は、この時点で、セッションIDを含む セッションデータを保存すべきではない(SHOULD NOT)。 セッション ストレージと永続性を参照。

        2. message type を "license-request" とする。

        それ以外の場合:
        1. message を、sanitized init data に基づいて requested license type のライセンス要求を生成できるようになる前に 処理する必要がある要求とする。

          後続の update() 呼び出しにおいて、CDM は、initDataType ごとに解釈される sanitized init data に基づいて requested license type のライセンス要求を生成しなければならない (MUST)。

        2. message typemessage の型を反映する "license-request" または "individualization-request" とする。

    10. 次の手順を実行するためにタスクを キューに入れる

      1. 前述の手順のいずれかがリソース不足により失敗した場合、 QuotaExceededErrorpromise を拒否する。

      2. 前述の手順のいずれかがその他の理由で失敗した場合、名前が適切な エラー名である新しい DOMExceptionpromise を拒否する。

      3. sessionId 属性を session id に設定する。

      4. このオブジェクトの callable 値を true に設定する。

      5. promiseundefined で解決する。

      6. session に対して "message" イベントをキューに入れる アルゴリズムを実行し、 message type および message を提供する。

  11. promise を返す。

load()

指定されたセッションのために保存されたデータをこのオブジェクトに読み込む。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの closing or closed 値が true である場合、 InvalidStateError で拒否されたpromiseを返す。

  2. このオブジェクトの uninitialized 値が false である場合、 InvalidStateError で拒否されたpromiseを返す。

  3. このオブジェクトの uninitialized 値を false とする。

  4. sessionId が空文字列である場合、新しく作成された TypeError で拒否されたpromiseを返す。

  5. このオブジェクトの session type に対して 永続セッションタイプか? アルゴリズムを実行した結果が false である場合、新しく作成された TypeError で拒否されたpromiseを返す。

  6. origin を、このオブジェクトの Documentオリジン とする。

  7. promise を新しいpromiseとする。

  8. 次の手順を並列に実行する。

    1. sanitized session ID を、sessionId の検証済みかつ/または サニタイズ済みバージョンとする。

      ユーザーエージェントは、sessionId値を CDM に渡す前に 徹底的に検証すべきである。少なくとも、長さおよび値が妥当であること (例えば、数十文字を超えず、英数字であること)の確認を含むべきである。

    2. 前述の手順が失敗した場合、または sanitized session ID が空である場合、 新しく作成された TypeErrorpromise を拒否する。

    3. このオブジェクトの Document 内に、 閉じられていない MediaKeySession オブジェクトで、その sessionId 属性が sanitized session ID であるものが存在する場合、 QuotaExceededErrorpromise を拒否する。

      言い換えれば、この閲覧コンテキスト内に、この sanitized session ID に対する閉じられていないセッションが、 型に関係なくすでに存在する場合、セッションを作成しない。

    4. expiration timeNaN とする。

    5. message を null とする。

    6. message type を null とする。

    7. cdm を、このオブジェクトの cdm instance 値により表される CDM インスタンスとする。

    8. cdm を使用して次の手順を実行する。

      1. origin 内に sanitized session ID のために 保存されたデータがない場合、promisefalse で 解決し、このアルゴリズムの並列手順を中止する。

      2. 保存されたセッションの session type が、現在の MediaKeySessionsession type と同じでない場合、新しく作成された TypeErrorpromise を拒否する。

      3. session data を、origin 内の sanitized session ID のために保存されたデータとする。これは、他の オリジンからのデータ、またはオリジンに関連付けられていないデータを 含んではならない(MUST NOT)。

      4. 任意の Document 内に、 閉じられていない MediaKeySession オブジェクトで、session data を表すものが存在する場合、 QuotaExceededErrorpromise を拒否する。

        言い換えれば、任意の閲覧コンテキスト内に、この sanitized session ID に対する閉じられていない永続 セッションがすでに存在する場合、セッションを作成しない。

      5. session data を読み込む。

      6. session data が、そのセッションに対する有効期限 時刻を示す場合、expiration time をその有効期限時刻とする。

      7. メッセージを送信する必要がある場合、次の手順を実行する。

        1. messagesession data に基づいて 生成されたメッセージとする。

        2. message type を、そのメッセージに適切な MediaKeyMessageType とする。

    9. 次の手順を実行するためにタスクを キューに入れる

      1. 前述の手順のいずれかが失敗した場合、適切な エラー名promise を拒否する。

      2. sessionId 属性を sanitized session ID に設定する。

      3. このオブジェクトの callable 値を true に設定する。

      4. 読み込まれたセッションにいずれかのキーに関する情報(既知のキー)が含まれる場合、 session に対してキー ステータスを更新するアルゴリズムを実行し、各キーの キーID を、適切な MediaKeyStatus と共に提供する。

        キーのステータスを確実に判断するために追加処理が必要な場合は、 "status-pending" を使用する。 1つ以上のキーについて追加処理が完了したら、実際のステータスを用いて キー ステータスを更新するアルゴリズムを再度実行する。

      5. expiration time を提供して、session に対して 有効期限を更新するアルゴリズムを 実行する。

      6. promisetrue で解決する。

      7. message が null でない場合、session に対して "message" イベントをキューに入れる アルゴリズムを実行し、message type および message を提供する。

  9. promise を返す。

update()

ライセンスを含むメッセージをCDM に提供する。

response パラメーターは、CDM に提供されるメッセージを含む。 内容はキーシステム固有である。実行可能コードを含んではならない (MUST NOT)。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの closing or closed 値が true である場合、 InvalidStateError で拒否されたpromiseを返す。

  2. このオブジェクトの callable 値が false である場合、 InvalidStateError で拒否されたpromiseを返す。

  3. response が空配列である場合、新しく作成された TypeError で拒否されたpromiseを返す。

  4. response copyresponse パラメーターの内容のコピーとする。

  5. promise を新しいpromiseとする。

  6. 次の手順を並列に実行する。

    1. sanitized response を、response copy の検証済みかつ/または サニタイズ済みバージョンとする。

      ユーザーエージェントは、応答を CDM に渡す前に徹底的に検証すべきである。 これには、値が妥当な制限内にあることの確認、無関係なデータまたは フィールドの除去、事前解析、サニタイズ、および/または完全に サニタイズされたバージョンの生成が含まれることがある。ユーザーエージェントは、 フィールドの長さおよび値が妥当であることを確認すべきである。 不明なフィールドは拒否または削除されるべきである。

    2. 前述の手順が失敗した場合、または sanitized response が空である場合、 新しく作成された TypeErrorpromise を拒否する。

    3. message を null とする。

    4. message type を null とする。

    5. session closed を false とする。

    6. cdm を、このオブジェクトの cdm instance 値により表される CDM インスタンスとする。

    7. cdm を使用して次の手順を実行する。

      1. sanitized response の形式が何らかの点で無効である場合、 新しく作成された TypeErrorpromise を拒否する。

      2. sanitized response を処理し、次の一覧から最初に一致する条件の 規定に従う。

        sanitized response がライセンスまたはキーを含む場合

        これには、初期ライセンス、更新されたライセンス、およびライセンス 更新メッセージが含まれる。

        sanitized response を処理し、次の一覧から最初に一致する条件の 規定に従う。

        sessionType が "temporary" であり、sanitized response が、含まれる ライセンス、キー、または類似のセッションデータを含むセッション データを保存すべきであると指定していない場合
        セッションデータを一切保存せずに sanitized response を処理する。
        sessionType が "persistent-license" であり、sanitized response が永続化可能なライセンスを含む場合
        sanitized response を処理し、sanitized response に含まれるライセンス/キーおよび関連する セッションデータを保存する。そのようなデータは、このオブジェクトの Documentオリジン のみがアクセスできるように保存されなければならない(MUST)。
        それ以外の場合

        新しく作成された TypeErrorpromise を拒否する。

        セッションストレージと 永続性も参照。

        各セッションのキーを含む状態情報は、たとえ重複するキーIDを 含んでいても、1つのセッションを閉じることが他のセッションにおける 観測可能な状態に影響しないような方法で保存されなければならない (MUST)。

        sanitized response がキーおよび/または関連データを 含む場合、cdm はキーIDでインデックス付けされたキーおよび 関連データを(メモリ内に)保存する可能性が高い。

        セッション内の置換アルゴリズムはキー システム依存である。

        CDM 実装が、標準かつ妥当に高い MediaKeySession オブジェクトあたりの最小キー数、標準の置換アルゴリズム、および 標準かつ妥当に高い MediaKeySession オブジェクト数をサポートすることが推奨される(RECOMMENDED)。 これにより、妥当な数のキーローテーションアルゴリズムを ユーザーエージェント間で実装できるようになり、異なるキーを使用する 同じ要素内のさまざまなストリーム(例: 適応ストリーム、さまざまな 音声および動画トラック)を含むユースケースで再生中断の可能性を 減らすことができる。

        sanitized responseライセンス 破棄の記録の確認応答を含み、 sessionType が "persistent-license" である場合

        次の手順を実行する。

        1. キーセッションを閉じ、 このオブジェクトに関連付けられた保存済みセッションデータ すべてを消去する。これには sessionId およびライセンス 破棄の記録が含まれる。

          後続の load() を、このオブジェクトの sessionId の値で呼び出すと、そのセッションIDについて保存されたデータが 存在しないため失敗する。

        2. session closed を true に設定する。

        それ以外の場合
        セッションデータを一切保存せずに sanitized response を処理する。

        例えば、sanitized response は別の message イベントを生成するために使用される情報を含むことがある。この場合、 内容を sessionType に照らして検証する必要はない。

      3. メッセージを送信する必要がある場合、次の手順を実行する。

        1. message をそのメッセージとする。

        2. message type を、そのメッセージに適切な MediaKeyMessageType とする。

    8. 次の手順を実行するためにタスクを キューに入れる

      1. session closed が true である場合:

        このオブジェクトに対して、理由 "release-acknowledged" でセッション閉鎖 アルゴリズムを実行する。

        それ以外の場合:

        次の手順を実行する。

        1. このオブジェクトについて CDM既知であるキーの集合が 変化した、またはいずれかのキーのステータスが変化した場合、 session に対してキー ステータスを更新するアルゴリズムを実行し、各 既知のキーのキーID を、適切な MediaKeyStatus と共に提供する。

          キーのステータスを確実に判断するために追加処理が必要な場合は、 "status-pending" を使用する。 1つ以上のキーについて追加処理が完了したら、実際の ステータスを用いてキー ステータスを更新するアルゴリズムを再度実行する。

        2. セッションの有効期限時刻が 変化した場合、新しい有効期限時刻を提供して、 session に対して 有効期限を 更新するアルゴリズムを実行する。

        3. 前述の手順のいずれかが失敗した場合、名前が適切な エラー名である新しい DOMExceptionpromise を拒否する。

        4. message が null でない場合、session に対して"message" イベントをキューに入れるアルゴリズムを実行し、 message type および message を提供する。

      2. promiseundefined で解決する。

  7. promise を返す。

close()

アプリケーションがセッションをもはや必要としておらず、CDM が セッションに関連付けられたリソースを解放して閉じるべきであることを示す。 永続化されたデータは解放または消去されるべきではない。

返されるpromiseは要求が処理されたときに解決され、 closed 属性のpromiseは、 セッションが閉じられたときに "closed-by-application" で解決される。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの closing or closed 値が true である場合、 undefined で解決されたpromiseを返す。

  2. このオブジェクトの callable 値が false である場合、 InvalidStateError で拒否されたpromiseを返す。

  3. promise を新しいpromiseとする。

  4. このオブジェクトの closing or closed 値を true に設定する。

  5. 次の手順を並列に実行する。

    1. cdm を、このオブジェクトの cdm instance 値により表される CDM インスタンスとする。

    2. cdm を使用して、このオブジェクトに関連付けられた キーセッションを閉じる。

      キーセッションを閉じると、明示的に保存されていないライセンスおよび キーは破棄される。

    3. 次の手順を実行するためにタスクを キューに入れる

      1. promiseundefined で解決する。

      2. このオブジェクトに対して、理由 "closed-by-application" でセッション 閉鎖アルゴリズムを実行する。

  6. promise を返す。

remove()

セッションに関連付けられたすべてのライセンスおよびキーを削除する。永続セッションタイプでは、リリースメッセージの確認応答が update() により処理されると、 各セッションタイプについて定義されるように、その他のセッションデータが消去される。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST)。

  1. このオブジェクトの closing or closed 値が true である場合、 InvalidStateError で拒否されたpromiseを返す。

  2. このオブジェクトの callable 値が false である場合、 InvalidStateError で拒否されたpromiseを返す。

  3. promise を新しいpromiseとする。

  4. 次の手順を並列に実行する。

    1. cdm を、このオブジェクトの cdm instance 値により表される CDM インスタンスとする。

    2. message を null とする。

    3. message type を null とする。

    4. cdm を使用して次の手順を実行する。

      1. セッションにいずれかのライセンスおよび/またはキーが関連付けられている場合:

        1. セッションに関連付けられたライセンスおよび/またはキーを破棄する。

          これは、それらがメモリ内、永続ストア内、またはその両方にあるかに かかわらず、ライセンスおよび/またはキーの破棄を意味する。

        2. このオブジェクトの session type の値について、次の一覧の手順に従う。

          "temporary"

          次の手順を続行する。

          "persistent-license"
          1. record of license destruction を、 このオブジェクトにより表されるライセンスの ライセンス 破棄の記録とする。

          2. record of license destruction を保存する。

          3. message を、 record of license destruction を 含む、または反映するメッセージとする。

    5. 次の手順を実行するためにタスクを キューに入れる

      1. セッション内のすべてのキーIDを、それぞれに対する "released" MediaKeyStatus 値と共に提供して、session に対して キー ステータスを更新する アルゴリズムを実行する。

      2. NaN を提供して、session に対して 有効期限を更新するアルゴリズムを 実行する。

      3. 前述の手順のいずれかが失敗した場合、名前が適切な エラー名である新しい DOMExceptionpromise を拒否する。

      4. message type を "license-release" とする。

      5. promiseundefined で解決する。

      6. messagenull でない場合、session に対して "message" イベントをキューに入れるアルゴリズムを実行し、 message type および message を提供する。

  5. promise を返す。

6.3 MediaKeyStatusMap インターフェイス

MediaKeyStatusMap オブジェクトは、 キーIDから関連付けられたキーの現在の ステータスへの読み取り専用マップである。

キーのステータスは、そのキーが現在使用されているかどうか、およびメディアデータから独立している。

例えば、キーに現在満たせない出力要件がある場合、そのキーのステータスは、そのキーが メディアデータの復号に必要であったか、または現在必要であるかに関係なく、適宜 "output-downscaled" または "output-restricted" であるべきである。

WebIDL[Exposed=Window, SecureContext] interface MediaKeyStatusMap {
  iterable<BufferSource,MediaKeyStatus>;
  readonly attribute unsigned long size;
  boolean has (BufferSource keyId);
  (MediaKeyStatus or undefined) get (BufferSource keyId);
};

6.3.1 属性

size 型は unsigned long, readonly

既知のキーの数。

6.3.2 メソッド

has()

keyId により識別されるキーのステータスが既知である場合、true を返す。

get()

keyId により識別されるキーの MediaKeyStatus を返す。keyId により識別されるキーのステータスが既知でない場合は undefined を返す。

このインターフェイスには、iterable によりもたらされる entrieskeysvaluesforEach および @@iterator メソッドがある [WebIDL]。

反復処理される値の組は、すべての既知のキーについて、 キーIDと関連付けられた MediaKeyStatus 値から形成される組の集合の スナップショットであり、キーIDでソートされる。キーIDは次のように比較される: 長さ m のキーID A と長さ nB について、 m <= n となるように割り当てたとき、Am オクテットが B の最初の m オクテットより辞書順で小さい、 またはそれらのオクテットが等しく、かつ m < n である場合に限り、 A < B とする。

WebIDLenum MediaKeyStatus {
  "usable",
  "expired",
  "released",
  "output-restricted",
  "output-downscaled",
  "usable-in-future",
  "status-pending",
  "internal-error"
};

MediaKeyStatus 列挙型は次のように定義される:

列挙型の説明
usable CDM は、キーが現在復号に使用可能であると確信している。
現在復号に使用可能ない可能性があるキーは、 このステータスを持ってはならない(MUST NOT)。
expired キーは、その有効期限時刻が過ぎたため、もはや 復号に使用可能ではない。
expiration 属性により表される時刻は、 現在時刻より前でなければならない(MUST)。セッション内の他のすべてのキーもこのステータスを 持たなければならない(MUST)。
released キー自体はもはや CDM に利用可能ではないが、 ライセンス破棄の記録など、 キーに関する情報は利用可能である。
output-restricted キーに関連付けられた出力制限があり、現在満たすことができない。 このキーで復号されたメディアデータは、出力制限に従って必要であれば提示をブロックされることがある。 アプリケーションは、そのキーに関連付けられた出力制限をトリガーするストリームの使用を 避けるべきである。
output-downscaled キーに関連付けられた出力制限があり、現在満たすことができない。 このキーで復号されたメディアデータは、出力制限に従って必要であれば低い品質 (例: 解像度)で提示されることがある。アプリケーションは、そのキーに関連付けられた 出力制限をトリガーするストリームの使用を避けるべきである。
ダウンスケーリングのサポートは任意である(OPTIONAL)。 アプリケーションは、出力要件を満たせないときに中断のない再生を確保するために ダウンスケーリングに依存すべきではない(SHOULD NOT)。
usable-in-future 開始時刻が将来であるため、キーはまだ復号に使用可能ではない。 キーはその開始時刻に達すると使用可能になる。
status-pending キーのステータスはまだ不明であり、判定中である。ステータスは判定されたときに実際の ステータスで更新される。
internal-error キーは、他の値とは無関係な CDM 内のエラーのため、現在復号に使用可能ではない。この値は アプリケーションが対処可能なものではない。

MediaKeyMessageEvent オブジェクトは、message イベントに使用される。

WebIDLenum MediaKeyMessageType {
  "license-request",
  "license-renewal",
  "license-release",
  "individualization-request"
};

MediaKeyMessageType は次のように定義される:

列挙型の説明
license-request メッセージは新しいライセンスの要求を含む。
license-renewal メッセージは既存のライセンスを更新する要求を含む。
license-release メッセージはライセンス破棄の記録を含む。
individualization-request メッセージはアプリ支援個別化(または 再個別化)の要求を含む。
他のすべてのメッセージと同様に、メッセージ内の識別子は オリジンおよびプロファイルごとに特徴的で なければならず(MUST)、かつ 特徴的な永続識別子で あってはならない(MUST NOT)。
WebIDL[Exposed=Window, SecureContext]
interface MediaKeyMessageEvent : Event {
  constructor(DOMString type, MediaKeyMessageEventInit eventInitDict);
  readonly attribute MediaKeyMessageType messageType;
  readonly attribute ArrayBuffer         message;
};

6.4.1 属性

messageType 型は MediaKeyMessageType, readonly
メッセージの型。

実装は、アプリケーションにメッセージ型の処理を要求してはならない(MUST NOT)。 実装は、メッセージを区別しないアプリケーションをサポートしなければならず (MUST)、アプリケーションにメッセージ型の処理を要求しては ならない(MUST NOT)。 具体的には、キーシステムは、すべての型のメッセージを単一のURLに 渡すことをサポートしなければならない(MUST)。

この属性により、アプリケーションはメッセージを解析せずにメッセージを区別できる。 これは任意のアプリケーションおよび/またはサーバー最適化を可能にすることを意図しているが、 アプリケーションはこれを使用する必要はない。

message 型は ArrayBuffer, readonly
CDM からのメッセージ。メッセージはキー システム固有である。

6.4.2 MediaKeyMessageEventInit

WebIDLdictionary MediaKeyMessageEventInit : EventInit {
  required MediaKeyMessageType messageType;
  required ArrayBuffer         message;
};
6.4.2.1 辞書 MediaKeyMessageEventInit メンバー
messageType 型は MediaKeyMessageType
メッセージの型。
message 型は ArrayBuffer
メッセージ。

6.5 イベント概要

このセクションは非規範的である。

イベント名 インターフェイス 送出される条件...
keystatuseschange Event セッション内のキーまたはその状態に変更があった。
message MediaKeyMessageEvent CDM がセッション用のメッセージを生成した。

6.6 アルゴリズム

6.6.1 "message" イベントをキューに入れる

"message" イベントをキューに入れるアルゴリズムは、 MediaKeySession オブジェクトに message イベントをキューに入れる。このアルゴリズムの実行要求には、対象の MediaKeySession オブジェクト、 message type、および message が含まれる。

message は、暗号化された形式であっても、 特徴的な永続識別子を含んではならない (MUST NOT)。 message は、MediaKeySession オブジェクトの use distinctive identifier 値が false である場合、暗号化された形式であっても 特徴的な識別子を含んではならない (MUST NOT)。

次の手順を実行する。

  1. session を、指定された MediaKeySession オブジェクトとする。

  2. バブルせず、キャンセル可能でもない、message という名前のイベントを作成するために タスクを キューに入れる。そのイベントは MediaKeyMessageEvent インターフェイスを使用し、 その type 属性を message に設定し、isTrusted 属性を true に初期化して、session に対して配送する。

    イベントインターフェイス MediaKeyMessageEvent は次を持つ:

6.6.2 キー ステータスを更新する

キーステータスを更新するアルゴリズムは、 MediaKeySession既知のキーの集合、または 1つ以上のキーのステータスを更新する。このアルゴリズムの実行要求には、対象の MediaKeySession オブジェクト、および キーIDと関連付けられた MediaKeyStatus の組の シーケンスが含まれる。

このアルゴリズムは常にタスク内で実行される。

次の手順を実行する。

  1. session を、関連付けられた MediaKeySession オブジェクトとする。

  2. input statuses を、キーIDと関連付けられた MediaKeyStatus の組のシーケンスとする。

  3. statusessessionkeyStatuses 属性とする。

  4. statuses の内容を置き換えるため、次の手順を実行する。

    1. statuses を空にする。

    2. input statuses 内の各組について。

      1. pair をその組とする。

      2. pair のキーIDに対するエントリーを statuses に挿入し、 値を pairMediaKeyStatus 値にする。

    この手順の効果は、属性への既存の参照を無効にすることなく、sessionkeyStatuses 属性の内容が置き換えられることである。この置換はスクリプトの観点ではアトミックである。 すなわち、スクリプトは部分的に投入されたシーケンスを決して見てはならない (MUST NOT)。

  5. session に対して keystatuseschange という名前のイベントを発火するために タスクを キューに入れる

  6. session を作成した MediaKeys オブジェクトが mediaKeys 属性である 各メディア要素に対して、必要なら再生を再開しようとする アルゴリズムを実行するためにタスクを キューに入れる

6.6.3 有効期限を 更新する

有効期限を更新するアルゴリズムは、 MediaKeySession有効期限時刻を 更新する。このアルゴリズムの実行要求には、対象の MediaKeySession オブジェクトと、 NaN であってもよい新しい有効期限時刻が含まれる。

このアルゴリズムは常にタスク内で実行される。

次の手順を実行する。

  1. session を、関連付けられた MediaKeySession オブジェクトとする。

  2. expiration timeNaN とする。

  3. 新しい有効期限時刻が NaN でない場合、expiration time をその有効期限時刻とする。

  4. sessionexpiration 属性を、 時刻として表される expiration time に設定する。

6.6.4 セッション 閉鎖

セッション閉鎖アルゴリズムは、CDM によりキーセッションが閉じられた後に、 MediaKeySession の状態を更新する。 このアルゴリズムの実行要求には、対象の MediaKeySession オブジェクト および MediaKeySessionClosedReason が含まれる。

このアルゴリズムは常にタスク内で実行される。

セッションが閉じられると、それに関連付けられたライセンスおよびキーは、もはや メディアデータの復号に 利用可能ではない。このアルゴリズムが実行された後、このオブジェクトについて すべての MediaKeySession メソッドは失敗し、 それ以上のイベントはキューに入れられない。

CDM は、セッションが不要になったときやシステムリソースが失われたときなど、 任意の時点でセッションを閉じることがある。その場合、 CDM状態変化の監視 アルゴリズムが変更を検出し、このアルゴリズムを実行する。

他のセッション内のキーは、キーIDが重複していても影響を受けてはならない (MUST)。

このアルゴリズムが実行された後、このアルゴリズムによりキューに入れられたイベントの イベントハンドラーは実行されるが、それ以上のイベントはキューに入れることができない。 その結果、セッションを閉じることの結果として CDM からメッセージを送信することはできない。

次の手順を実行する。

  1. session を、関連付けられた MediaKeySession オブジェクトとする。

  2. promisesessionclosed 属性とする。

  3. promise が解決済みである場合、これらの手順を中止する。

  4. sessionclosing or closed 値を true に設定する。

  5. 空のシーケンスを提供して、session に対して キーステータスを更新する アルゴリズムを実行する。

  6. NaN を提供して、session に対して 有効期限を更新するアルゴリズムを 実行する。

  7. promise を提供された理由で解決する。

6.6.5 CDM状態変化の監視

CDM状態変化の監視アルゴリズムは、CDM 状態のさまざまな側面が変化したときに必要な手順を実行する。

このアルゴリズムは、他のアルゴリズムで扱われない CDM 状態変化にのみ適用される。 例えば、update() は、 メッセージ、キーステータス変化、および/または有効期限変化を生じることがあるが、 それらはすべてそのアルゴリズム内で処理される。

このアルゴリズムは常にメインイベントループと並列に実行される。

次の手順を実行する。

  1. sessionMediaKeySession オブジェクトとする。

  2. cdm を、sessioncdm instance 値により表される CDM インスタンスとする。

  3. cdm にまだ送信されていない送信メッセージがある場合、次の手順を実行するために タスクを キューに入れる

    1. message type および message を、それぞれメッセージ型と メッセージとする。

    2. sessionmessage type および message を渡して、 "message" イベントをキューに入れるアルゴリズムを実行する。

  4. cdmsession既知であるキーの集合、 または1つ以上のキーのステータスを変更した場合、次の手順を実行するために タスクを キューに入れる

    1. statuses を、session既知である 各キーについて1つの組を含む、キーIDと MediaKeyStatus 値の組の一覧とする。

    2. session および statuses を渡して、 キーステータスを更新する アルゴリズムを実行する。

  5. cdmsession有効期限時刻を変更した場合、 次の手順を実行するために タスクを キューに入れる

    1. expiration timesession の新しい有効期限時刻とする。

    2. session および expiration time を渡して、 有効期限を更新する アルゴリズムを実行する。

  6. cdmsession を閉じた場合、適切な MediaKeySessionClosedReason 値で、session に対して セッション閉鎖アルゴリズムを実行するために タスクを キューに入れる

  7. cdm がハードウェアコンテキストのリセットにより利用不可になった場合、理由 "hardware-context-reset" で CDM利用不可アルゴリズムを 実行するためにタスクを キューに入れる

  8. cdm がその他の理由で利用不可になった場合、理由 "internal-error" で CDM利用不可アルゴリズムを実行するために タスクを キューに入れる

6.7 例外

メソッドは、返されたpromiseを単純例外 [WEBIDL] または DOMException で拒否することにより エラーを報告する。アルゴリズムでは、[WEBIDL] の次の 単純 例外および DOMException 名が使用される。 アルゴリズムで指定された原因は各名前と並べて示されるが、これらの名前は他の理由にも 使用してよい(MAY)。

名前 考えられる原因(網羅的ではない)
TypeError パラメーターが空である。
無効な初期化データ。
無効な応答形式。
永続ライセンスが "temporary" セッションに提供された。
NotSupportedError 既存の MediaKeys オブジェクトを 削除できない。
キーシステムがサポートされていない。
初期化データタイプがキー システムによりサポートされていない。
セッションタイプがキー システムによりサポートされていない。
初期化データがキー システムによりサポートされていない。
操作がキー システムによりサポートされていない。
InvalidStateError 既存の MediaKeys オブジェクトを 現時点では削除できない。
セッションはすでに使用されている。
セッションはまだ初期化されていない。
セッションは閉じられている。
QuotaExceededError MediaKeys オブジェクトを追加の HTMLMediaElement と共に使用できない。
この sessionId に対して閉じられていないセッションがすでに存在する。
新しいセッションまたはライセンス要求を作成するためのリソースが不足している。

6.8 セッションストレージと永続性

この節は、アルゴリズムを補完するセッションストレージおよび永続性の概要を提供する。

次の要件は、ストレージおよび永続性の要件に加えて適用される。

このオブジェクトの session type に対して 永続的セッション型か? アルゴリズムを実行した結果が false である場合、ユーザーエージェントおよび CDM は、いかなる時点においても、 セッションに関連する記録またはデータを永続化してはならない。 これには、ライセンス、キー、ライセンス 破棄の記録、および セッション ID が含まれる。

この節の残りは、永続的セッション型か? アルゴリズムが true を返すセッション型に適用される。

CDM は、 update() が最初に呼び出されるまで、 セッション ID を含むセッションデータを保存すべきではない。 具体的には、CDM は、generateRequest() アルゴリズムの間にセッションデータを保存すべきではない。これにより、 アプリケーションがそのセッションを認識し、最終的にそれを削除する必要があることを 確実に把握できる。

セッションに関連付けられたデータはすべて、セッションが消去されるときに消去されなければ ならない。たとえば、update() において、 ライセンス破棄の記録 の確認応答を処理する場合などである。永続 データを参照。

CDM は、所与のセッションのデータが、任意の Document 内で閉じられていない 1 つの MediaKeySession オブジェクト内にのみ存在することを 確実にしなければならない。 つまり、sessionId パラメーターによって指定されるセッションを表す MediaKeySession がすでに存在する場合、 それが generateRequest() によって作成したオブジェクトがまだアクティブであるためであれ、または load() によって別の オブジェクトに読み込まれているためであれ、 load() は失敗しなければ ならない。セッションは、それをこれまで表したすべてのオブジェクトが 閉じられている場合にのみ、再び読み込まれても よい

永続的セッション型か? アルゴリズムが true を返す型を使用してセッションを作成するアプリケーションは、後で remove() を使用して まず削除プロセスを開始し、その後、メッセージ交換を伴う場合があるその削除プロセスが 正常に完了することを確実にすることによって、保存されたデータを削除すべき であるCDM も適宜セッションを削除してもよいが、アプリケーションはこれに依存すべきでは ない

永続的ストレージをサポートする場合の追加の考慮事項については、10. セキュリティおよび11. プライバシーを参照。

7. HTMLMediaElement 拡張

このセクションは、暗号化メディア拡張がサポートされるときの HTMLMediaElement [HTML] への追加および変更を指定する。

次の内部値が HTMLMediaElement に追加される:

HTMLMediaElement の振る舞いに対して、 次の変更が行われる:

promiseを返すメソッドについては、すべてのエラーは返されたPromiseを拒否することで非同期に報告される。 これには [WEBIDL] 型マッピングエラーも含まれる。

アルゴリズムの手順は、promiseを拒否するときには常に中止される。

WebIDL[Exposed=Window] partial interface HTMLMediaElement {
  [SecureContext] readonly        attribute MediaKeys?   mediaKeys;
                                  attribute EventHandler onencrypted;
                                  attribute EventHandler onwaitingforkey;
  [SecureContext] Promise<undefined> setMediaKeys (MediaKeys? mediaKeys);
};

7.1 属性

mediaKeys 型は MediaKeys, readonly, nullable

このメディア要素について、暗号化されたメディアデータを 復号するときに使用される MediaKeys

onencrypted 型は EventHandler

encrypted イベントのイベントハンドラー。すべての HTMLMediaElement により、コンテンツ属性およびIDL属性の両方としてサポートされなければならない (MUST)。

onwaitingforkey 型は EventHandler

waitingforkey イベントの イベントハンドラー。すべての HTMLMediaElement により、コンテンツ属性およびIDL属性の両方としてサポートされなければならない(MUST)。

7.2 メソッド

setMediaKeys()

再生中にメディアデータを復号するときに使用する MediaKeys を提供する。

再生中に関連付けられた MediaKeys オブジェクトを消去または 置換することのサポートは、実装品質の問題である。多くの場合、それは悪いユーザー体験、 または拒否されたpromiseをもたらす。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければならない (MUST):

  1. このオブジェクトの attaching media keys 値が true である場合、 InvalidStateError で拒否されたpromiseを返す。

  2. mediaKeysmediaKeys 属性が 同じオブジェクトである場合、undefined で解決されたpromiseを返す。

  3. このオブジェクトの attaching media keys 値を true とする。

  4. promise を新しいpromiseとする。

  5. 次の手順を並列に実行する。

    1. 次の条件すべてが成立する場合:

      • mediaKeys が null でなく、

      • mediaKeys により表される CDM インスタンスが、 すでに別のメディア要素で使用中であり、

      • ユーザーエージェントがそれをこの要素で使用できない

      その場合、このオブジェクトの attaching media keys 値を false とし、 promiseQuotaExceededError で拒否する。

    2. mediaKeys 属性が null でない場合、次の手順を実行する:

      1. ユーザーエージェントまたは CDM が 関連付けの削除をサポートしない場合、このオブジェクトの attaching media keys 値を false とし、promiseNotSupportedError で拒否する。

      2. 関連付けを現在削除できない場合、このオブジェクトの attaching media keys 値を false とし、 promiseInvalidStateError で拒否する。

        例えば、一部の実装では再生中の削除を許可しない場合がある。

      3. mediaKeys 属性により表される CDM インスタンスを メディア データの復号に使用することを停止し、メディア要素との関連付けを削除する。

      4. 前の手順が失敗した場合、このオブジェクトの attaching media keys 値を false とし、promise を適切な エラー名で拒否する。

    3. mediaKeys が null でない場合、次の手順を実行する:

      1. mediaKeys により表される CDM インスタンスを、 メディア データの復号用にメディア要素と関連付ける。

      2. 前の手順が失敗した場合、次の手順を実行する:

        1. mediaKeys 属性を null に設定する。

        2. このオブジェクトの attaching media keys 値を false とする。

        3. 名前が適切な エラー名である新しい DOMExceptionpromise を拒否する。

      3. メディア要素に対して タスクを キューに入れることで、 必要なら 再生を再開しようとする アルゴリズムを実行する。

    4. mediaKeys 属性を mediaKeys に設定する。

    5. このオブジェクトの attaching media keys 値を false とする。

    6. promiseundefined で解決する。

  6. promise を返す。

7.3 MediaEncryptedEvent インターフェイス

MediaEncryptedEvent オブジェクトは、encrypted イベントに使用される。

WebIDL[Exposed=Window]
interface MediaEncryptedEvent : Event {
    constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict = {});
    readonly        attribute DOMString    initDataType;
    readonly        attribute ArrayBuffer? initData;
};

7.3.1 属性

initDataType 型は DOMString, readonly
initData 属性に含まれる 初期化データ初期化データタイプを示す。
initData 型は ArrayBuffer, readonly, nullable
イベントの初期化データ

7.3.2 MediaEncryptedEventInit

WebIDLdictionary MediaEncryptedEventInit : EventInit {
  DOMString    initDataType = "";
  ArrayBuffer? initData = null;
};
7.3.2.1 辞書 MediaEncryptedEventInit メンバー
initDataType 型は DOMString、 既定値は ""
初期化データ タイプ
initData 型は ArrayBuffer、 nullable、既定値は null
初期化データ

7.4 イベント概要

このセクションは非規範的である。

イベント名 インターフェイス 送出される条件... 前提条件
encrypted MediaEncryptedEvent ユーザーエージェントが初期化データに、メディアデータ内で遭遇する。 要素の readyState は、 HAVE_METADATA 以上である。
注記

要素が再生中である、または再生済みである可能性がある。

waitingforkey Event 再生はキー待ちでブロックされている。 readyState は、 HAVE_CURRENT_DATA 以下である。 要素の playback blocked waiting for key 値は新たに true である。

7.5 アルゴリズム

7.5.1 メディアデータは暗号化ブロックを含む可能性がある

メディアデータは暗号化ブロックを含む可能性があるアルゴリズムは、ユーザーエージェントが メディアデータを再生する前に MediaKeys オブジェクトの 指定を要求する場合、再生を一時停止する。 このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. media elementmediaKeys 属性が null であり、かつ実装が、暗号化されている可能性があるメディアデータを デコードする前に MediaKeys オブジェクトの指定を 要求する場合、次の手順を実行する:

    これらの手順は、アプリケーションが setMediaKeys() を呼び出して MediaKeys オブジェクトを提供する前に、 メディアデータ を提供した場合に到達することがある。CDM の選択は、使用されるパイプラインおよび/またはデコーダーに 影響する可能性があるため、一部の実装は、 MediaKeys オブジェクトを setMediaKeys() に渡すことで CDM が指定されるまで、 暗号化ブロックを含む可能性があるメディアデータの再生を遅延させることがある。

    1. media element に対して キーを待機アルゴリズムを 実行する。

    2. 再生を再開するシグナルを待つ。

7.5.2 初期化データに遭遇

初期化データに遭遇アルゴリズムは、メディア データ内で遭遇した 初期化データについて、 encrypted イベントを キューに入れる。このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. initDataType を空文字列とする。

  3. initData を null とする。

  4. メディアデータCORS 同一オリジン であり、かつない 混在コンテンツである場合、次の手順を実行する:

    1. initDataType を、初期化データの初期化 データ型を表す文字列とする。

    2. initData を初期化データとする。

    注記

    メディア要素は「アップグレード可能コンテンツ」 [MIXED-CONTENT] の読み込みを許可する場合があるが、 ユーザーエージェントは、そのような メディアデータからの初期化データをアプリケーションに公開してはならない

  5. バブルせず、 キャンセル可能でない encrypted という名前のイベントを作成するために タスクを キューに入れる。そのイベントは MediaEncryptedEvent インターフェイスを使用し、 その type 属性を encrypted に設定し、その isTrusted 属性を true に初期化して、これを media element に送出する。

    イベントインターフェイス MediaEncryptedEvent は次を持つ:

    注記

    readyState は変更されず、どのアルゴリズムも 中止されない。このイベントは単に情報を提供するだけである。

    注記

    メディアデータが CORS 同一オリジンない、または混在コンテンツである場合、 initData 属性は null になる。アプリケーションは、別のソースから初期化データを取得してもよい。

7.5.3 暗号化ブロックに遭遇

暗号化ブロックに遭遇アルゴリズムは、暗号化メディアデータのブロックを復号用にキューに入れ、 可能であれば復号を試みる。このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. block を、暗号化メディアデータのブロックとする。

  3. blockmedia elementencrypted block queue の末尾に追加する。

  4. media elementdecryption blocked waiting for key 値が false である場合、 復号を試みるアルゴリズムを実行する。

7.5.4 復号を 試みる

復号を試みるアルゴリズムは、復号用にキューに入れられたメディアデータの復号を試みる。 このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. media elementencrypted block queue が空である場合、 これらの手順を中止する。

  3. media elementmediaKeys 属性が null でない場合、次の手順を実行する:

    1. media keys を、その属性により参照される MediaKeys オブジェクトとする。

    2. cdm を、media keyscdm instance 値により表される CDM インスタンスとする。

    3. cdm が何らかの理由でもはや使用可能でない場合、次の手順を実行する:

      1. メディア データが破損している手順を、 リソース 取得アルゴリズムの一部として実行する。

      2. ハードウェアコンテキストリセットの場合は理由 "hardware-context-reset"、 それ以外の場合は "internal-error" を用いて、media keys に対して CDM 利用不可アルゴリズムを実行する。

      3. これらの手順を中止する。

    4. media keys により作成された MediaKeySession閉じられていないものが 少なくとも1つ存在する場合、次の手順を実行する:

      この確認により、cdm の読み込みが完了しており、一致するキーが利用可能であるための 前提条件を満たしていることが保証される。

      1. block を、media elementencrypted block queue 内の最初のエントリーとする。

      2. block key IDblock のキーIDとする。

        キーIDは通常、コンテナーにより指定される。

      3. cdm を使用して次の手順を実行する:

        1. available keys を、media keys により作成された セッション内のキーの和集合とする。

        2. block key を null とする。

        3. available keys のいずれかが block key ID に対応し、かつ復号に使用可能で ある場合、session をそのキーを含む MediaKeySession オブジェクトとし、block key をそのキーとする。

          複数のセッションが、block key ID について 復号に使用可能な キーを含む場合、どのセッションおよびキーを使用するかは キー システム依存である。

        4. 前の手順を実行した結果として available keys のいずれかの ステータスが変化した場合、影響を受けた各 session に対して タスクを キューに入れることで、 キーステータスを更新する アルゴリズムを実行し、セッション内のすべての キーIDを、 それぞれに対する適切な MediaKeyStatus 値と共に提供する。

        5. block key が null でない場合、次の手順を実行する:

          1. cdm を使用し、block key を用いて block を復号する。

          2. 次の一覧から最初に一致する条件の手順に従う:

            復号が失敗した場合
            1. メディア データが破損している手順を リソース 取得アルゴリズムの一部として実行する。

            2. cdm がもはや使用可能でない場合、 ハードウェアコンテキストリセットの場合は理由 "hardware-context-reset"、 それ以外の場合は "internal-error" を用いて、media keys に対して CDM 利用不可アルゴリズムを実行する。

            3. これらの手順を中止する。

            それ以外の場合
            1. blockmedia elementencrypted block queue の先頭から削除する。

            2. 復号されたブロックを通常どおり処理する。

              言い換えれば、ブロックをデコードする。

            3. このアルゴリズムの先頭に戻る。

            すべての復号問題(例えば、誤ったキーの使用)が復号失敗に なるわけではない。そのような場合、ここではエラーは発火されないが、 デコード中に発火されることがある。

          それ以外の場合、どのセッションにも block key ID のキーが ないため、続行する。

  4. media elementdecryption blocked waiting for key 値を true に設定する。

    この手順は、block について復号に使用可能なキーがないときに到達する。

    ユーザーエージェントが、復号できないブロックより前のブロックを(完全な動画フレーム すべてなど、可能な限り)レンダリングすると、 キーを待機アルゴリズムを実行する。

    このアルゴリズムをここで直接実行しないのは、実装が現在の再生位置より先の メディアデータを復号およびデコードしても、可視の振る舞いに影響しないようにするためである。

フレームベースの暗号化では、これは、メディア要素がリソース 取得アルゴリズムの一部としてフレームをデコードしようとするとき、次のように実装されることがある:

  1. encrypted を false とする。

  2. フレームが暗号化されているかどうかを検出する。

    フレームが暗号化されている場合
    上記の手順を実行する。
    それ以外の場合
    続行する。
  3. フレームをデコードする。

  4. フレームをレンダリング用に提供する。

7.5.5 キーを 待機

キーを待機アルゴリズムは、waitingforkey イベントを キューに入れ、 readyState を更新する。これは、HTMLMediaElement オブジェクトが再生中である可能性がある 状態であり、その readyStateHAVE_FUTURE_DATA 以上である場合にのみ呼び出されるべきである。このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. media elementplayback blocked waiting for key 値が true である場合、これらの手順を中止する。

  3. media elementplayback blocked waiting for key 値を true に設定する。

    上記の手順の結果として、メディア要素がまだブロックされた メディア要素でない場合、そうなる。その場合、メディア要素は再生を停止する。

  4. 次の一覧から最初に一致する条件の手順に従う:

    直近の現在の 再生位置のデータが利用可能である場合

    media elementreadyStateHAVE_CURRENT_DATA に設定する。

    それ以外の場合

    media elementreadyStateHAVE_METADATA に設定する。

    言い換えれば、現在の 再生位置の動画フレームおよび音声データが、暗号化されていない、および/または正常に 復号されたためにデコード済みである場合、 readyStateHAVE_CURRENT_DATA に設定する。それ以外の場合、以前はそうであったがデータがもはや利用可能でない場合も含め、 readyStateHAVE_METADATA に設定する。

  5. media element に対して waitingforkey という名前の イベントを発火するために タスクを キューに入れる

  6. 再生を中断する。

7.5.6 必要なら再生を再開しようとする

必要なら再生を再開しようとするアルゴリズムは、メディア要素がキーを待ってブロックされており、 必要なキーが現在復号に使用可能である場合、再生を再開する。 このアルゴリズムの実行要求には、対象の HTMLMediaElement オブジェクトが含まれる。

次の手順を実行する。

  1. media element を、指定された HTMLMediaElement オブジェクトとする。

  2. media elementplayback blocked waiting for keyfalse である場合、これらの手順を中止する。

  3. media element に対して 復号を試みる アルゴリズムを実行する。

  4. ユーザーエージェントが現在の 再生位置再生方向へ 進めることができる場合:

    1. media elementdecryption blocked waiting for key 値を false に設定する。

    2. media elementplayback blocked waiting for key 値を false に設定する。

      上記の手順の結果として、メディア要素はもはや ブロックされた メディア要素ではなくなり、したがって再生が再開されることがある。

    3. media elementreadyState 値を、適切に HAVE_CURRENT_DATAHAVE_FUTURE_DATA または HAVE_ENOUGH_DATA に設定する。

      HAVE_CURRENT_DATA を超える状態および canplaythrough イベントは、現在のキーを超えたキーの可用性を考慮しない(または考慮する可能性が低い)。

      ready状態の変更は、HTMLMediaElement イベントを、ここで 説明されるように発火させることもある。

7.6 メディア要素の制限

このセクションは非規範的である。

CDM により処理されたメディアデータは、通常の方法で WebプラットフォームAPIを通じて利用できないことがある(MAY) (例えば、CanvasRenderingContext2DdrawImage() メソッドおよび AudioContext MediaElementAudioSourceNodeを 使用する場合)。 この仕様は、そのようなメディアデータが利用不能になる条件を定義しないが、メディアデータが そのようなAPIを通じて利用できない場合、それらはメディアデータがまったく存在しないかのように 振る舞ってよい(MAY)。

メディアレンダリングがUAにより実行されない場合、例えばハードウェアベースのメディアパイプラインの 場合、CSS Transforms など、HTMLのレンダリング機能の全セットが利用できないことがある (MAY)。あり得る制限の1つは、動画メディアが、ウィンドウの端に平行な 辺を持ち、通常の向きである矩形領域にのみ表示されるよう制約されることがある (MAY)。

8. 実装要件

この節では、ユーザーエージェントとキーシステムの両方に対する実装要件を定義する。これには CDM およびサーバーが含まれ、 アルゴリズムでは明示的に扱われない場合がある。 ここでの要件および仕様全体を通じた要件は、CDM がユーザーエージェントから分離されているか、その一部であるかにかかわらず、 すべての実装に適用される。

8.1 CDM の制約

ユーザーエージェントの実装者は、CDM が、 この仕様の機能を使用した保護メディアの再生に合理的に必要とされない情報、 ストレージ、またはシステム機能にアクセスしないことを保証しなければならない。 具体的には、CDM は以下を行ってはならない:

ユーザーエージェントの実装者は、上記の要件を満たすためにさまざまな技法を使用してよい。 たとえば、自身の CDM も実装する ユーザーエージェントの実装者は、上記をそのコンポーネントの設計要件として含めてもよい。 第三者の CDM を利用するユーザーエージェントの実装者は、それが禁止された情報およびコンポーネントに アクセスできない制約された環境(たとえば「サンドボックス」)内で実行されることを保証してもよい。

8.2 メッセージおよび通信

CDM への、および CDM からのすべてのメッセージおよび通信、たとえば ライセンスサーバーとの間のものは、ユーザーエージェントを通過しなければならないCDM は、直接の 帯域外ネットワークリクエストを行ってはならない直接個別化で 記述されるもの以外のすべてのメッセージおよび通信は、この仕様で定義される API を介して アプリケーションを通過しなければならない。具体的には、アプリケーション固有、 オリジン固有、 またはコンテンツ固有の情報を含む通信、あるいは アプリケーションによって指定された URL またはそのオリジンに基づく URL に送信される通信はすべて、 API を通過しなければならない。 これには、すべてのライセンス交換メッセージが含まれる。

8.3 永続データ

永続データには、CDM によって、または CDM の代わりにユーザーエージェントによって保存され、 MediaKeys オブジェクトの破棄後に存在するすべてのデータが含まれる。 具体的には、CDM によって、または CDM の代わりにユーザーエージェントによって保存される、 任意の識別子(特徴的な識別子を含む)、 ライセンス、キー、キー ID、またはライセンス破棄の記録が含まれる。

8.3.1 オリジン固有かつ閲覧プロファイル固有のキーシステム ストレージを使用する

アプリケーションまたはライセンスサーバーに可視な形でメッセージまたは振る舞いに影響し得る 永続データは、オリジン固有かつ 閲覧プロファイル固有の方法で保存されなければならず (MUST)、プライベートブラウジングセッションへ漏洩したり、 そこから漏洩したりしてはならない(MUST NOT)。 具体的には、ただし網羅的ではなく、セッションデータ、ライセンス、キー、およびオリジンごとの 識別子は、オリジンごと、 かつ閲覧プロファイルごとに保存されなければならない (MUST)。

セッションストレージと永続性を参照。

8.3.2 永続データを消去できるようにする

永続データを使用する実装は、この仕様で定義されるAPIを介するなど外部からも、 クライアントデバイス上でも、それがもはや取得できないように、そのデータをユーザーが 消去できるようにしなければならない(MUST)。

ユーザーエージェントは次をすべきである(SHOULD):

  • 永続データを、Cookie [COOKIES] などの他のサイトデータと 同様に扱う。具体的には:

    • ユーザーが、Cookie [COOKIES] およびその他の サイトデータと共に永続データを消去できるようにする。

    • ユーザーが、閲覧履歴を消去するユーザーエージェント機能の一部として 永続データを消去できるようにする。

    • "すべてのデータを削除" 機能に永続データを含める。

    • 永続データを他のサイトデータと同じUI位置に表示する。

  • ユーザーが、特に特定のサイトに関連付けられたCookie [COOKIES]、データベースなどを 忘れる "Forget about this site" 機能の一部として、オリジン ごと、かつ閲覧プロファイルごとに 永続データを消去できるようにする。

  • 永続データを消去する操作が十分にアトミックであり、同時に消去されなかった別種の ローカル保存データに依存して、新しい識別子が古い識別子と再相関される "cookie resurrection" 型の再相関を防止することを確保する。 データの不完全な消去を参照。

  • これらのインターフェイスを、ユーザーがデータの不完全な消去の 可能性を理解しやすく、Cookie [COOKIES] およびWebストレージを 含む、データを永続化するすべての機能に関連付けられたデータを同時に削除できるように 表示する。

  • キーシステムを 無効化および再有効化するためのインターフェイスを、ユーザーがデータの 不完全な消去の可能性を理解しやすく、すべての永続ストレージ機能内の そのようなデータすべてを同時に削除できるように表示する。

  • ユーザーが、オリジン ごと、および/またはすべてのオリジンについて、永続データを明示的に削除できるようにする。

8.3.3 永続データを暗号化または難読化する

ユーザーエージェントは、永続データを潜在的に機微なものとして扱うべきである (SHOULD)。この情報の公開により、ユーザーのプライバシーが 侵害される可能性は十分にある。この目的のため、ユーザーエージェントは永続データが安全に 保存され、データを削除するときには基盤となるストレージから速やかに削除されることを 確保すべきである(SHOULD)。

8.4 アプリケーションに公開される値

アプリケーションに公開される、または CDM による使用などを通じて アプリケーションが推測可能な値は、識別子として設計されているかどうかにかかわらず、 クライアントまたはユーザーを識別するために使用される可能性がある。このセクションは、 そのような懸念を回避、または少なくとも軽減するための要件を定義する。 識別子については追加の要件がある。

8.4.1 オリジンごと・プロファイルごとの値を使用する

アプリケーションに公開される、または推測可能なすべての特徴的な値は、 オリジンおよび 閲覧プロファイルごとに一意でなければならない (MUST)。すなわち、この仕様で定義されるAPIを使用して あるオリジンで 使用される値は、APIを使用する他の任意のオリジンで使用される値と異ならなければならず (MUST)、ある閲覧 プロファイルで使用される値は、オリジンにかかわらず、他の任意のプロファイルで 使用される値と異ならなければならない(MUST)。 そのような値は、プライベートブラウジングセッションへ、またはそこから漏洩してはならない (MUST NOT)。

オリジンおよびプロファイルをまたぐ値は、アプリケーションにより関連付け不能でなければならない (MUST)。これは、複数のオリジンまたはプロファイルからの値を相関させ、 同じクライアントまたはユーザーから来たと判断するようなことが可能であってはならない (MUST NOT)ことを意味する。具体的に、オリジン非依存および/または プロファイル非依存の値からオリジンごとの値を導出する実装は、適切な不可逆特性を持つ 導出関数を使用するなど、上記の関連付け不能性を確保する方法でそれを行わなければならない (MUST)。

8.4.2 値を消去できるようにする

永続データを消去できるようにするの要件の結果として、 アプリケーションに公開されるすべての永続化された値は、この仕様で定義されるAPIを介するなど 外部からも、クライアントデバイス上でも、その値がもはや取得、観測、または推測できないように 消去可能でなければならない(MUST)。

消去後に値が後で必要になった場合、新しいアプリケーションにより 関連付け不能な値が生成されなければならない(MUST)。

8.5 識別子

実装による識別子、特に特徴的な 識別子または特徴的な永続識別子の使用は、プライバシー上の懸念をもたらす。 このセクションは、そのような懸念を回避、または少なくとも軽減するための要件を定義する。 アプリケーションに公開される値の要件も、 アプリケーションに公開される識別子に適用される。

8.5.1 特徴的な識別子および永続識別子の使用を制限または回避する

  • 実装は、特徴的な識別子または 特徴的な永続識別子の使用を避けるべきである (SHOULD)。

    例えば、個々のクライアントではなく、クライアントまたはデバイスのグループに適用される 識別子またはその他の値を使用する。

  • 実装は、特定の CDM インスタンスおよびセッションに関連するポリシーを 強制するために必要な場合にのみ、特徴的な 識別子または特徴的な永続識別子を使用すべきである (SHOULD)。

    例えば、"temporary" および "persistent-license" セッションは異なる要件を持つ場合がある。

  • 特徴的な 識別子または特徴的な永続識別子を使用する実装は、それらを使用しない選択肢を サポートすべきである(SHOULD)。そのようなサポートを持つ実装は、 ユーザーがこの選択肢を選択できる能力を公開すべきである (SHOULD)。

    サポートされる場合、アプリケーションは distinctiveIdentifier = "not-allowed" を使用してこのモードを選択できる。 そのような選択肢を選択することは、 requestMediaKeySystemAccess() 呼び出しの結果、および/またはその後生成されるセッションから生成される ライセンス要求に影響する場合がある。

    この実装能力をユーザーが選択または選ぶためのアクセスを提供することにより、 ユーザーはより高いプライバシーを維持しながらコンテンツにアクセスできる場合がある。

8.5.2 識別子を暗号化する

特徴的な識別子および特徴的な永続的 識別子は、クライアントの外部に公開される場合、 メッセージ交換レベルで暗号化されなければならない。 その他すべての識別子は、クライアントの外部に公開される場合、 メッセージ交換レベルで暗号化されるべきである。その 暗号化は、識別子の暗号文の任意の 2 つのインスタンスが、 復号キーを保持するエンティティによってのみ 関連付け可能であることを保証しなければ ならない

注記

識別子は、次の方法で公開される場合がある:

  • message イベントを介してアプリケーションへ。

  • サーバーからのメッセージ内。たとえば、 update() に渡されるもの。

  • 個別化の一部として。

CDM は、暗号化キーがそのキーシステムに対して有効なサーバーに 属することを検証しなければならない。アプリケーションに公開される識別子については、 これはサーバー証明書を使用して実装されても よい

サーバーは、特徴的な識別子を、それを送信した CDM 以外のいかなるエンティティにも公開しては ならない

注記

具体的には、それをアプリケーションに提供したり、 CDM へのメッセージ内に暗号化せずに含めたりすべきではない。 これは、識別子、またはその識別子を含むメッセージを、その特定の CDM によってのみ復号可能となるように暗号化することで実現できる。

8.5.3 オリジンごと・プロファイルごとの識別子を使用する

特徴的な永続識別子を除くすべての識別子は、 オリジンおよび 閲覧プロファイルごとに一意でなければならない (MUST)。8.4.1 オリジンごと・プロファイルごとの値を使用するを参照。

8.5.4 関連付け不能な識別子を使用する

実装によりアプリケーションへ公開されるすべての識別子は、暗号化された形であっても、 特徴的な識別子を含め、 アプリケーションにより関連付け不能で なければならない(MUST)。対象は、 オリジン間、 閲覧プロファイル間、および 識別子の消去をまたぐ場合である。

8.5.5 識別子を消去できるようにする

永続データを消去可能にすることの 要件の結果として、特徴的な値または潜在的なすべての識別子は、 特徴的な永続的 識別子を除き、値が、この仕様で定義される API を介する場合などの外部と、 クライアントデバイス上の両方で、もはや取得、観測、または推論できないように 消去可能でなければならない

特徴的な 識別子を使用する実装は、ユーザーが 特徴的な識別子を消去できるようにしなければ ならない特徴的な 永続的識別子を使用する実装は、ユーザーが 特徴的な永続的識別子に関連付けられた値を 消去できるようにしなければならない

消去された後、特徴的な識別子などの値が その後必要になった場合には、新しいアプリケーションによって 関連付け不可能な値を生成しなければならない

8.6 個別化

識別子、特に特徴的な識別子は、 個別化またはプロビジョニングと呼ばれるプロセスを通じて生成または取得される場合がある。 結果として得られる識別子は、アプリケーションによって関連付け不可能でなければ ならず、それらの使用は、単一の プロファイルからの単一のオリジンにのみ公開されなければならない。このプロセスは、 識別子が消去された後などに、複数回実行されても よい

このプロセスは、ユーザーエージェントによって直接、またはアプリケーションを通じて実行されなければ ならない。2 種類の個別化についての仕組み、 フロー、および制約は、次の節で説明されるように異なる。どの方法が使用されるかは、 CDM の実装、および この仕様の要件、特に以下の要件の適用に依存する。

注記

distinctiveIdentifier は、特徴的な識別子および 特徴的な永続的 識別子を、個別化を含めて使用 できるかどうかを制御する。具体的には、そのような識別子は、 MediaKeySystemAccess のメンバーであり、 MediaKeys オブジェクトの作成に使用される distinctiveIdentifier メンバーの値が "required" である場合にのみ、 そのような識別子を使用 できる。

8.6.1 直接個別化

直接個別化は、CDM と、オリジンおよび アプリケーションに依存しないサーバーとの間で実行される。そのサーバーはオリジンに依存しないが、 個別化の結果により、CDM は、この仕様の他の要件に従ってオリジン固有の識別子を 提供できるようになる。このプロセスはユーザー エージェントによって実行されなければならず、この仕様で定義される API を使用してはならない

注記

たとえば、そのようなプロセスは、ユーザーエージェントまたは CDM ベンダーによってホストされる 事前に決定されたサーバーと通信することにより、クライアントデバイスを初期化し、および/または 単一の閲覧プロファイル用の オリジンごと消去可能な識別子を取得する場合がある。場合によっては、 クライアントデバイスからの特徴的な永続的識別子を 使用する、またはその他の永続的識別子を使用することがある。

そのような個別化については、すべてのメッセージ交換は:

  • ユーザーエージェントによって処理され、ユーザー エージェントのネットワークスタックを介してユーザーエージェントによって実行されなければならない

  • CDM によって直接実行されてはならない

  • この仕様で定義される API を介して、アプリケーションに渡されては、またはアプリケーションを通じて渡されては ならない

  • いかなるオリジンおよびアプリケーションからも独立して選択された URL に送信されなければ ならない

  • すべての特徴的な識別子および特徴的な 永続的識別子を暗号化しなければならない

  • TLS を使用しなければならない

実装は、オリジン、オリジン固有または アプリケーション固有の情報、またはオリジンと関連付け可能な値を、 暗号化された形であっても、集中型サーバーに公開してはならない。なぜなら、 これにより、ユーザーまたはデバイスが訪問したすべてのオリジンの中央記録が作成される可能性があるためである。

8.6.2 アプリ支援個別化

アプリケーション支援個別化は、CDM とアプリケーション、 これにはアプリケーションが選択したサーバーを含む、との間で実行され、 オリジンごとの識別子をもたらす。この プロセスは、この仕様で定義される API を介して実行されなければならず、 その他の通信方法を伴ってはならない。 API の他のすべての使用と同様に、このプロセスは よい 1 つ以上の特徴的な 識別子を使用してもよいが、 特徴的な永続的 識別子を使用しては、またはオリジン固有でない値を使用しては、 暗号化された形であってもならない。このプロセスが1 つ以上の特徴的な 識別子を使用する場合、結果として得られる識別子も定義上 特徴的な識別子である。

そのような個別化については、すべてのメッセージ交換は:

  • この仕様で定義される API を介して、アプリケーションに渡される、または アプリケーションを通じて渡されなければならない

  • 関連するすべてのmessage イベントについて、メッセージ型 "individualization-request" を使用しなければならない

  • ユーザーエージェントによって実行されてはならない

  • CDM によって直接実行されてはならない

  • 特徴的な永続的 識別子を使用してはならず、またそれを含んでもならない

  • オリジン固有でないクライアントごとの情報を含んではならない

  • 識別子 要件を遵守しなければならない

    注記

    これには、オリジンおよびプロファイルごとに一意であり、 消去可能な値のみを使用し、 要求されるとおりにそれらを暗号化することが含まれる。

  • 実行可能コードを CDM に提供してはならない

特徴的な識別子を含む 関連付け可能な値がプロセスで使用される場合、実装は、 オリジン、オリジン固有またはアプリケーション固有の情報、または オリジンと関連付け可能な値を、暗号化された形であっても、 集中型サーバーに公開してはならない。なぜなら、これにより、 ユーザーまたはデバイスが訪問したすべてのオリジンの中央記録が作成される可能性があるためである。

適切な予防措置を講じれば、そのような個別化は 直接個別化よりも優れたプライバシーを提供できるが、 特徴的な 識別子を使用することのないモデルほど優れてはいない。そのような設計の利点を維持し、 その他のプライバシー上の懸念をもたらさないようにするために、そのような実装およびそれを サポートするアプリケーションは、個別化メッセージを中央サーバーまたはアプリケーション作者が 制御していないその他のサーバーに延期または転送することを避けるべきである

8.7 複数キーのサポート

実装は、各 MediaKeySession オブジェクト内で複数のキーを サポートしなければならない(MUST)。

複数キーがどのようにサポートされるかの仕組みは実装詳細であるが、 アプリケーションおよびこの仕様で定義されるAPIからは透過的でなければならない (MUST)。

実装は、再生中のキー間のシームレスな切り替えをサポートしなければならない (MUST)。これには、同じ MediaKeySession 内のキーと、 別個の MediaKeySession オブジェクト内のキーの両方が 含まれる。

8.8 初期化データタイプのサポート

8.8.1 生成されるライセンスはコンテンツタイプに依存しない

実装は、サポートする任意の初期化データタイプで生成されたライセンスを、 任意のコンテンツタイプで使用できるようにすべきである(SHOULD)。

そうでない場合、例えば requestMediaKeySystemAccess() アルゴリズムが、MediaKeySystemConfiguration を拒否することがある。これは、その initDataTypes の1つが、 videoCapabilities の1つでサポートされていないためである。

8.8.2 メディアデータからの抽出をサポートする

サポートされるコンテナーに現れる可能性がある、サポートされる任意の 初期化データタイプについて、 ユーザーエージェントは、その種類の 初期化データを各そのようなサポートされるコンテナーから 抽出することをサポートしなければならない (MUST)。

言い換えれば、初期化データタイプのサポートを示すことは、 ライセンス要求を生成するための CDM サポートと、コンテナー固有のタイプについてはそれを コンテナーから抽出するためのユーザーエージェントサポートの両方を意味する。これは、 実装が任意のサポートされるコンテンツタイプから任意のサポートされる 初期化データを解析できなければならないことを 意味しない

8.9 サポートされるメディア

このセクションは、この仕様の実装によりサポートされるコンテンツ(メディア リソース)の特性を定義する。

8.9.1 暗号化されていないコンテナー

メディアコンテナーは暗号化されてはならない(MUST NOT)。 この仕様は、ユーザーエージェントがメディアデータのいずれも復号することなく メディアコンテナーを解析できる能力に依存する。これには、 暗号化ブロックに 遭遇および初期化データに遭遇 アルゴリズム、ならびにHTMLMediaElement [HTML] の標準機能、例えばシークのサポートが 含まれる。

8.9.2 相互運用可能に暗号化されている

すべてのトラックを含むメディアリソースは、 キーまたは複数のキーが提供されたときに、完全に指定され互換性のある方法でコンテンツを復号できる、 コンテナー固有の "common encryption" 仕様に従って暗号化およびパッケージ化されなければならない (MUST)。

注記

Encrypted Media Extensions Stream Format Registry は、そのようなストリーム形式への参照を提供する。

8.9.3 暗号化されていないインバンド支援コンテンツ

キャプション、解説音声、トランスクリプトなどのインバンド支援コンテンツは、 暗号化されるべきではない(SHOULD NOT)。

そのようなトラックの復号、特にそれらをユーザーエージェントに戻して提供できるようにすることは、 実装により一般的にはサポートされていない。したがって、そのようなトラックを暗号化すると、 ユーザーエージェント実装のアクセシビリティ機能で広く利用できなくなる。

アクセシビリティ情報が利用可能な形式で利用できることを確保するため、暗号化された インバンド支援コンテンツをサポートすることを選択する実装については、a) CDM は 復号済みデータをユーザーエージェントに提供しなければならず(MUST)、b) ユーザーエージェントはそれを同等の暗号化されていない 支援コンテンツと同じ方法で処理しなければならない(MUST)。 例えば、時限テキストトラック [HTML] として公開するためである。

9. 共通キー システム

すべてのユーザーエージェントは、このセクションで説明される共通のキーシステムを サポートしなければならない(MUST)。

これにより、完全にオープンソースであるものを含むすべてのユーザーエージェントで サポートが保証される、共通の基礎的な機能レベルが存在することが確保される。 したがって、基本的な復号のみを必要とするコンテンツプロバイダーは、コンテンツ保護プロバイダーと 連携する必要なく、すべてのプラットフォームで動作する単純なアプリケーションを構築できる。

9.1 Clear Key

"org.w3.clearkey" キーシステムは、ソースを復号するために 平文のクリア(暗号化されていない)キーを使用する。追加のクライアント側コンテンツ保護は 必要ない。このキーシステムを以下で説明する。

9.1.1 能力

次は、Clear Keyキーシステム固有の能力をどのようにサポートするかを 説明する:

9.1.2 振る舞い

次は、Clear Keyキーシステム固有の振る舞いをどのように実装するかを 説明する:

  • generateRequest() アルゴリズムでは:

    • 生成される message は、 ライセンス要求形式で説明されるように UTF-8で符号化されたJSONオブジェクトである。

    • 要求は、sanitized init data からキーIDを抽出することにより生成される。

    • "type" メンバー値は sessionType パラメーターの値である。

  • sessionId 属性は、 32ビット整数で表現可能な数値である。

  • expiration 属性は 常に NaN である。

  • update() アルゴリズムでは:

    • response パラメーターは、 ライセンス形式で説明されるJWK Set、 または ライセンス解放確認応答形式で 説明されるUTF-8で符号化されたJSONオブジェクトのいずれかである。

    • 最初の場合、sanitized response は、音声/動画タイプに対して有効な長さの 少なくとも1つの有効なJWKキーを持つ有効なJWK Setでない場合、無効とみなされる。 2番目の場合、sanitized response は、有効なJSONオブジェクトでない場合、 無効とみなされる。

  • 型が "persistent-license" のセッションについては、 remove() アルゴリズムで、 record of license destruction を反映する message は、 ライセンス解放形式で説明されるUTF-8で符号化された JSONオブジェクトである。

  • keyStatuses 属性 メソッドは、初期状態では update() を 介して提供されたすべてのキーIDを、ステータス "usable" と共に含む。 remove() アルゴリズムが実行されると、 keyStatuses 属性は 空の一覧に設定される。

  • 初期化データ: 実装は、登録済み 初期化データタイプ [EME-INITDATA-REGISTRY] の 任意の組み合わせをサポートしてもよい(MAY)。 実装は、"keyids" 型 [EME-INITDATA-KEYIDS]、 およびユーザーエージェントがサポートするコンテンツタイプに適したその他の型を サポートすべきである(SHOULD)。

9.1.3 ライセンス要求形式

このセクションは、message イベントの message 属性を介してアプリケーションに提供されるライセンス要求の形式を説明する。

形式は、次のメンバーを含むJSONオブジェクトである:

"kids"
キーIDの配列。 配列の各要素は、キーID値を含むオクテット列のbase64url符号化である。
"type"
要求された MediaKeySessionType

MediaKeyMessageEvent オブジェクトの ArrayBuffer message 属性に含まれる場合、JSON文字列はEncoding仕様 [ENCODING] で指定されるUTF-8で符号化される。 アプリケーションは、TextDecoder インターフェイス [ENCODING] を使用して、ArrayBufferの内容をJSON文字列に デコードしてもよい(MAY)。

9.1.3.1

このセクションは非規範的である。

次の例は、2つのキーIDに対する一時ライセンスのライセンス要求である。 (改行は読みやすさのためだけのものである。)

{
  "kids": [
    "LwVHf8JLtPrv2GUXFW2v_A",
    "0DdtU9od-Bh5L3xbv0Xf_A"
  ],
  "type": "temporary"
}

9.1.4 ライセンス形式

このセクションは、update() メソッドの response パラメーターを介して提供されるライセンスの形式を説明する。

形式は、JSON Web Key (JWK) 仕様 [RFC7517] で定義されるように、復号に使用される 対称キーの表現を含むJSON Web Key (JWK) Setである。

セット内の各JWKについて、パラメーター値は次のとおりである:

"kty" (key type)
"oct" (オクテット列)。
"k" (key value)
対称キー値を含むオクテット列のbase64url符号化。
"kid" (key ID)
キー ID値を含むオクテット列のbase64url符号化。

JSONオブジェクトは任意の "type" メンバー値を持ってもよく(MAY)、 これは MediaKeySessionType 値のいずれかでなければならない(MUST)。指定されない場合、既定値 "temporary" が使用される。 update() アルゴリズムは、 この値を sessionType と比較する。

update() メソッドに ArrayBuffer response パラメーターとして渡されるとき、JSON文字列はEncoding仕様 [ENCODING] で指定されるUTF-8で符号化されなければならない (MUST)。アプリケーションは TextEncoder インターフェイス [ENCODING] を使用してJSON文字列を符号化してもよい (MAY)。

9.1.4.1

このセクションは非規範的である。

次の例は、単一の対称キーを含むJWK Setである。(改行は読みやすさのためだけのものである。)

{
  "keys": [{
    "kty": "oct",
    "k": "tQ0bJVWb6b0KPL6KtZIy_A",
    "kid": "LwVHf8JLtPrv2GUXFW2v_A"
  }],
  "type": "temporary"
}

9.1.5 ライセンス解放形式

このセクションは、message イベントの message 属性を介して提供されるライセンス解放メッセージの形式を説明する。

形式はJSONオブジェクトである。型 "persistent-license" のセッションについては、このオブジェクトは次のメンバーを含むものとする:

"kids"
キーIDの配列。 配列の各要素は、キーID値を含むオクテット列のbase64url符号化である。

MediaKeyMessageEvent オブジェクトの ArrayBuffer message 属性に含まれる場合、JSON文字列はEncoding仕様 [ENCODING] で指定されるUTF-8で符号化される。 アプリケーションは、TextDecoder インターフェイス [ENCODING] を使用して、ArrayBufferの内容をJSON文字列に デコードしてもよい(MAY)。

9.1.5.1 ライセンス破棄の記録を反映する メッセージの例

このセクションは非規範的である。

次の例は、2つのキーを含んでいた "persistent-license" セッションのライセンス解放である。(改行は読みやすさのためだけのものである。)

{
  "kids": [ "LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A" ]
}

9.1.6 ライセンス解放確認応答形式

このセクションは、update() メソッドの response パラメーターを介して提供されるライセンス解放確認応答の形式を説明する。

形式は、次のメンバーを含むJSONオブジェクトである:

"kids"
キーIDの配列。 配列の各要素は、キーID値を含むオクテット列のbase64url符号化である。

update() メソッドに ArrayBuffer response パラメーターとして渡されるとき、JSON文字列はEncoding仕様 [ENCODING] で指定されるUTF-8で符号化されなければならない (MUST)。アプリケーションは TextEncoder インターフェイス [ENCODING] を使用してJSON文字列を符号化してもよい (MAY)。

9.1.6.1

このセクションは非規範的である。

次の例は、2つのキーIDに対する一時ライセンスのライセンス要求である。 (改行は読みやすさのためだけのものである。)

{
  "kids": [
    "LwVHf8JLtPrv2GUXFW2v_A",
    "0DdtU9od-Bh5L3xbv0Xf_A"
  ]
}

9.1.7 base64url の使用

このセクションは非規範的である。

base64url およびその扱いに関する詳細については、[RFC7515] の "Base64url Encoding" 用語定義、および "Notes on implementing base64url encoding without padding" を参照。 具体的には、'=' パディングはなく、文字 '-' および '_' はそれぞれ '+' および '/' の代わりに 使用されなければならない(MUST)。

10. セキュリティ

10.1 入力データ攻撃および脆弱性

ユーザーエージェントおよびキーシステム実装は、メディア データ初期化データupdate() に渡されるデータ、 ライセンス、キーデータ、およびアプリケーションにより提供されるその他すべてのデータを、 信頼できないコンテンツおよび潜在的な攻撃ベクトルとして扱わなければならない (MUST)。それらは、関連する脅威を軽減するために適切な保護策を 使用し、そのようなデータを安全に解析、復号などするよう注意しなければならない (MUST)。ユーザーエージェントは、データを CDM に渡す前に検証すべきである (SHOULD)。

そのような検証は、CDM が、例えばDOMと同じ (サンドボックス化された)コンテキストで実行されない場合に特に重要である。

実装は、アプリケーションに、プログラム制御フローに影響するアクティブコンテンツまたは パッシブコンテンツを返してはならない(MUST NOT)。

例えば、generateRequest() に渡される初期化データの場合のように、 メディアデータ由来である可能性のあるURLその他の情報を公開することは安全ではない。 アプリケーションは使用するURLを決定しなければならない。 messageType 属性は、 message イベントの属性であり、 該当する場合、アプリケーションがURLの集合から選択するために使用できる。

10.2 CDM 攻撃および脆弱性

ユーザーエージェントは、ユーザーに安全にウェブを閲覧する方法を提供する責任を負う。この 責任は、第三者からの機能を含め、ユーザーエージェントによって使用されるあらゆる機能に適用される。 ユーザーエージェントの実装者は、キーシステムの実装者から十分な 情報を取得し、キーシステムとの統合による セキュリティ上の影響を適切に評価できるようにしなければならない。 ユーザーエージェントの実装者は、CDM 実装が、ユーザーエージェントが ユーザーにセキュリティを提供するために十分な制御を提供および/またはサポートすることを 保証しなければならない。ユーザーエージェントの実装者は、CDM 実装が、セキュリティ脆弱性が発生した場合に迅速かつ先回りして更新でき、かつ更新されることを 保証しなければならない

完全にサンドボックス化されていない、および/またはプラットフォーム機能を使用する CDM 実装を悪用すると、攻撃者が OS またはプラットフォーム機能にアクセスしたり、 権限昇格(たとえば、system または root として実行すること)を行ったり、および/または ドライバー、カーネル、ファームウェア、ハードウェアなどにアクセスしたりできる可能性がある。 そのような機能、ソフトウェア、およびハードウェアは、敵対的なソフトウェアまたは ウェブベースの攻撃に対して堅牢に書かれていない場合があり、特にユーザーエージェントと 比較して、セキュリティ修正で更新されない場合がある。CDM 実装におけるセキュリティ脆弱性の修正について、 更新がない、頻度が低い、または遅いことは、リスクを増大させる。そのような CDM 実装およびそれらを公開する UA は、すべてのデータの解析を含め、 セキュリティのあらゆる領域において特に注意しなければならない

注記

ユーザーエージェントは、クライアント OS、プラットフォーム、および/またはハードウェアの 一部である、またはそれらによって提供される CDM または基盤となる仕組みを 使用する場合、特に注意深くあるべきである。

ユーザーエージェントが、十分にサンドボックス化またはその他の方法で保護できない キーシステム実装をサポートすることを選択する場合、 ユーザーエージェントは、それを読み込むまたは呼び出す前に、ユーザーが十分に情報を提供され、および/または明示的に同意することを保証する べきである

注記

認証されていないオリジンに権限を付与することは、ネットワーク攻撃者が存在する場合、 任意のオリジンにその権限を付与することと同等である。永続化された同意の 悪用を参照。

10.3 ネットワーク攻撃

10.3.1 潜在的な攻撃

このセクションは非規範的である。

潜在的なネットワーク攻撃とその影響には次が含まれる:

  • DNSスプーフィング攻撃: 特定のドメイン(オリジン)に 属すると主張するホストが、本当にそのドメインからのものであることは保証できない。

  • 受動的ネットワーク攻撃: クライアントとサーバー間で送信されるデータ、 特徴的な 識別子および特徴的な永続 識別子を含むデータが、他のエンティティに見られないことは保証できない。 ユーザー追跡を参照。

  • 能動的ネットワーク攻撃: 追加のスクリプトまたはiframeがページ(この仕様で定義されるAPIを 正当な目的で使用するページと、それらを使用しないページの両方)に注入されないことは 保証できない。その結果は次のとおりである:

    • この仕様で定義されるAPIへの呼び出しが、任意のページに注入され得る。

    • 正当な理由でそれらを使用するページからの、この仕様で定義されるAPIへの呼び出しが、 要求される機能の変更、呼び出しの変更または追加、およびデータの変更または注入を 含め、操作され得る。入力データ攻撃および 脆弱性も参照。

    • クライアントとサーバー間で送信されるデータ、 特徴的な識別子および 特徴的な永続識別子を 含むデータが、他のエンティティにより閲覧および/または変更され得る。 ユーザー追跡を参照。

  • 永続化された同意の悪用: この仕様で定義されるAPIの 使用を要求するホストが、ユーザーが以前に同意を与えたホストであることは保証できない。 その結果、認証されていないオリジンに権限を付与することは、ネットワーク攻撃者が存在する場合、 任意のオリジンに権限を付与することと同等である。

10.3.2 軽減策

次の技術はリスクを軽減し得る:

TLSを使用する

TLSを使用するアプリケーションは、ユーザー、ユーザーの代わりに動作するソフトウェア、 および同じドメインからのものであることを示す証明書を持つTLSを使用する他のページだけが、 そのアプリケーションとやり取りできると確信できる。さらに、セキュアオリジンと組み合わせた オリジン固有の 権限は、アプリケーションに付与された権限がネットワーク攻撃者により悪用されないことを 確保する。

この仕様で定義されるAPIは、セキュアコンテキストでのみ公開される。 セキュアオリジンおよびトランスポートも参照。

混合コンテンツをブロックする

ユーザーエージェントは、TLSの使用など他の軽減策を損なう可能性のある安全でないコンテンツへの 潜在的な露出を避けるため、"Blockable Content" [MIXED-CONTENT] のブロックを含め、 混合コンテンツ [MIXED-CONTENT] を適切に扱わなければならない (MUST)。

ユーザーエージェントは、セキュリティをさらに高めるため、 "Optionally-blockable Content" [MIXED-CONTENT] を含むすべての混合コンテンツを ブロックすることを選択してよい(MAY)。 これは、信頼できないメディアデータCDM に渡されることを防ぐためである (CDM攻撃および脆弱性を参照)。

ユーザーエージェントは、他のユーザーエージェント機能(例: DOMコンテンツ)よりも大きい セキュリティ上の懸念を示すキーシステムオリジンにより アクセスされ得る前に、ユーザーが十分に知らされていること、および/または明示的な同意を 与えることを確保すべきである(SHOULD)。

そのようなメカニズムは、正当な使用が後続の悪意あるアクセスを可能にすることを避けるため、 オリジンごとで なければならず(MUST)、かつ 閲覧プロファイルごとでなければならない (MUST)。

この仕様で定義されるAPIをセキュアコンテキストに制限することにより、 ネットワーク攻撃者が、認証されていないオリジンに 付与された権限を悪用できないことが確保される。永続化された同意の悪用を参照。

10.4 iframe 攻撃

10.4.1 潜在的な攻撃

このセクションは非規範的である。

悪意あるページは、攻撃を隠したり、使用が正当なコンテンツプロバイダーからのものであるかのように 見せるなどしてユーザーを欺いたりする試みとして、正当なアプリケーションをiframe内でホストする 可能性がある。これは、セキュリティおよび/またはプライバシー上の 理由などにより、ユーザーに知らせる、または同意を要求する 実装に特に関連する。ネットワーク攻撃に加えて、攻撃者は、この仕様で定義されるAPIの 正当な使用を iframe 内でホストすることにより悪用しようとする可能性がある。 正当なアプリケーションに動作を実行させることで、攻撃者は既存の付与済み権限 (またはホワイトリスト化)を再利用したり、正当な要求または使用であるかのように見せたりできる。

10.4.2 軽減策

セキュリティおよび/またはプライバシー上の理由を含め、 ユーザーに知らせる、または同意を要求するユーザーエージェントは、 UIおよび同意の永続化を、トップレベルDocumentオリジン と、この仕様で定義されるAPIを使用する オリジンの 組み合わせに基づかせるべきである(SHOULD)。 これにより、ユーザーが要求を行うメイン文書を知らされ、1つの(正当な)組み合わせに対する権限の 永続化が悪意ある使用を気付かれないように誤って許可しないことが確保される。

作者は、他のエンティティが自身のアプリケーションを iframe 内でホストすることを 防ぐべきである(SHOULD)。正当なアプリケーション設計上の理由により ホストされることをサポートしなければならないアプリケーションは、この仕様で定義されるAPIを介して、 またはメディアデータとして、ホスト文書が CDMに渡される任意のデータを提供することを許可すべきではなく (SHOULD NOT)、かつホストフレームがこの仕様で定義されるAPIを 呼び出すことを許可すべきではない(SHOULD NOT)。

10.5 ディレクトリー横断攻撃

このセクションは非規範的である。

例えば geocities.com でコンテンツをホストするユーザーのように、 1つのホスト名を共有する異なる作者は、すべて1つのオリジンを共有する。 ユーザーエージェントは、パス名によってAPIへのアクセスを制限する機能を提供しない。

共有ホスト上でこの仕様で定義されるAPIを使用すると、ユーザーエージェントにより実装される オリジンベースのセキュリティおよびプライバシー軽減策が損なわれる。例えば、オリジンごとの 特徴的な識別子は1つのホスト名上のすべての作者により 共有され、永続化データはそのホスト上の任意の作者によりアクセスおよび操作される可能性がある。 後者は、例えば、そのようなデータの変更または削除により、ユーザーの特定コンテンツへの権利が 消去され得る場合に特に重要である。

パス制限機能がユーザーエージェントにより利用可能にされたとしても、通常のDOMスクリプティング セキュリティモデルにより、この保護を回避して任意のパスからデータにアクセスすることは 自明になる。

したがって、共有ホスト上の作者は、この仕様で定義されるAPIの使用を避けることが推奨される (RECOMMENDED)。そうすることは、ユーザーエージェントにおける オリジンベースのセキュリティおよびプライバシー軽減策を損なうためである。

11. プライバシー

ユーザーのデバイス上にキーシステムが存在すること、または使用されることは、 多くのプライバシー上の問題を引き起こし、それらは2つのカテゴリに分類される: (a) EMEインターフェイス自体またはキーシステムメッセージ内で 開示される可能性のあるユーザー固有情報、および (b) ユーザーのデバイス上に永続的に保存される 可能性のあるユーザー固有情報。

ユーザーエージェントは、ユーザーに自身のプライバシーに対する十分な制御を提供する責任を 負わなければならない(MUST)。 ユーザーエージェントは第三者の CDM 実装と統合することがあるため、 CDM 実装者は、以下で説明される技術を含むがこれらに限定されない、ユーザーがプライバシーを 制御できることを確保する適切な技術をユーザーエージェント実装者が実装できるよう、 十分な情報および制御を提供しなければならない(MUST)。

11.1 EMEおよびキーシステムにより開示される情報

EMEおよびキーシステムにより 開示される情報に関する懸念は、2つのカテゴリに分類される: (a) 非特定情報であるが、 それでもユーザーエージェントまたはデバイスのフィンガープリンティング可能性に寄与し得る情報に関する懸念、 および (b) ユーザー追跡に直接使用され得るユーザー固有情報。

11.2 フィンガープリンティング

悪意あるアプリケーションは、サポートされるキーシステムの一覧および関連情報を検出または列挙することにより、 ユーザーまたはユーザーエージェントをフィンガープリントできる可能性がある。 適切なオリジン保護が提供されない場合、これには訪問済みサイトやそれらのサイトについて保存された 情報の検出が含まれ得る。特に、キーシステムは、オリジン間で キーその他のデータを共有してはならない(MUST)。

この仕様のいくつかの機能は、フィンガープリンティングにわずかに寄与し得る能力情報を公開する:

11.3 情報漏洩

11.3.1 懸念

このセクションは非規範的である。

CDM、特にユーザーエージェントの外部で実装されるものは、Webプラットフォームと同じ基本的な 分離を持たないことがある。特にオリジンをまたぐ情報漏洩を避けるために対策を講じることが 重要である。これにはメモリ内データと保存済みデータの両方が含まれる。そうしない場合、 プライベートブラウジングセッションへの/からの情報漏洩、閲覧 プロファイルをまたぐ漏洩(オペレーティングシステムのユーザーアカウント間を含む)、 さらには異なるブラウザーまたはアプリケーション間での漏洩につながる可能性がある。

11.3.2 軽減策

そのような問題を避けるため、ユーザーエージェントおよび CDM 実装は、以下を保証しなければならない:

  • CDM は、CDM インスタンスという概念を持ち、それは MediaKeys オブジェクトと 1 対 1 で関連付けられる。

  • キー、ライセンス、その他のセッションデータ、およびセッションの存在は、 そのセッションを作成した MediaKeys オブジェクトに関連付けられた CDM インスタンスに制限される。

  • セッションデータは、MediaKeys オブジェクト間または CDM インスタンス間で共有されない。

  • セッションデータは、そのセッションを作成した MediaKeys オブジェクトに関連付けられていない メディア要素と共有されない。特に、これは、 セッションのキーは、その mediaKeys 属性が その MediaKeys オブジェクトでないメディア要素によって 読み込まれたコンテンツの復号に使用されてはならないことを意味する。

  • MediaKeys オブジェクトおよび基盤となる 実装は、オリジンの外部に情報を公開しない。

  • 永続化されたセッションデータは、該当する場合、オリジン ごとに保存される。

  • 要求しているオリジン によって保存されたデータのみを読み込むことができる。

  • この仕様で明示的に記述されている、またはユーザーの許可なしで他のウェブプラットフォーム API を通じて ページで利用可能である情報のいずれでもない情報を、CDM から抽出、派生、または推論することはできない。 これは、たとえば CDM メッセージ内の情報を含め、 クライアントデバイスの外部またはアプリケーションに公開されるあらゆる情報に適用される。

    注記

    この要件の対象となる情報の種類には、以下を含むがこれらに限定されない:

    • 位置情報(ジオロケーションを含む)

    • 特徴的な識別子以外の認証情報または識別子

    • OS アカウント名およびその他の潜在的な PII

    • 類似の情報を含む可能性があるローカルディレクトリパス。

    • ローカルネットワークの詳細(たとえば、デバイスのローカル IP アドレス)

    • Bluetooth、USB、およびユーザーメディアを含むがこれらに限定されないローカルデバイス。

    • この仕様で定義される API に関連付けられていない、またはその結果として保存されていないユーザー状態。

11.4 ユーザー追跡

11.4.1 懸念

このセクションは非規範的である。

第三者ホスト(または、広告主など、複数のサイトにコンテンツを配信させることができる 任意のエンティティ)は、特徴的な識別子または永続 データ、これにはライセンス、キー、キー ID、またはライセンス破棄の記録を含む、 CDM によって、またはその代わりに保存されたデータを使用して、 複数のセッションにわたって(オリジンおよび閲覧プロファイルをまたぐ場合を含む)ユーザーを追跡し、 ユーザーの活動または関心のプロファイルを構築する可能性がある。そのような追跡は、 ウェブプラットフォームの残りの部分によって提供されるプライバシー保護を損ない、 たとえば、他の方法では不可能な高度にターゲット化された広告を可能にする可能性がある。 ユーザーの実際の身元を認識しているサイト(たとえば、認証資格情報を要求する コンテンツプロバイダーまたは電子商取引サイト)と組み合わされると、これは、純粋に 匿名のウェブ利用の世界よりも高い精度で、抑圧的な集団が個人を標的にすることを 可能にする可能性がある。

この仕様の API の実装を介して取得され得る、ユーザーまたはクライアント固有の情報には、 以下が含まれる:

この仕様は、そのような情報が一般にユーザーエージェント(および関連する 閲覧 プロファイルのストレージ)の外部に、多くの場合 CDM 内に保存されるため、特有の懸念を提示する。

ライセンスおよびライセンス破棄の記録の内容は キーシステム固有であり、キー ID は任意の値を含み得るため、 これらのデータ項目は、ユーザー識別情報を保存するために悪用され得る。

キーシステムは、デバイスまたはデバイスのユーザーについての 永続的または半永続的な識別子にアクセスする、またはそれを作成する場合がある。 場合によっては、これらの識別子は特定のデバイスに安全な方法で結び付けられることがある。 これらの識別子がキーシステム メッセージに存在する場合、 デバイスおよび/またはユーザーが追跡される可能性がある。以下の緩和策が適用されない場合、 これには、時間の経過にわたるユーザー/デバイスの追跡と、所与のデバイスの複数ユーザーを 関連付けることの両方が含まれ得る。

そのような識別子、特に消去不能、非オリジン固有、 または永続的なものは、 Cookie [COOKIES] や URL に埋め込まれた セッション識別子などの既存の技法の追跡上の影響を上回ることに注意することが重要である。

緩和されない場合、そのような追跡は、 キーシステムの設計に応じて、次の 3 つの形態を取る可能性がある:

  • すべての場合において、そのような識別子は、キーシステムを完全にサポートする サイトおよび/またはサーバーで利用可能であると期待される(したがって キーシステム メッセージを解釈できる)ため、そのようなサイトによる追跡が可能になる。

  • キーシステムによって公開される識別子が オリジン固有でない場合、キーシステムを 完全にサポートする 2 つのサイトおよび/またはサーバーが共謀してユーザーを追跡する可能性がある。

  • キーシステム メッセージが、ユーザー識別子から 一貫した方法で派生した情報を含む場合、たとえば特定のコンテンツ項目に対する初期 キーシステム メッセージの一部が時間の経過によって変化せず、ユーザー識別子に依存しているような場合、 この情報は、任意のアプリケーションによって、時間の経過にわたってデバイスまたはユーザーを 追跡するために使用され得る。

さらに、キーシステムが、キーまたはその他のデータを保存し、 オリジン間で再利用することを許可する場合、2 つのオリジンが共謀し、 共通のキーにアクセスできる能力を記録することで、一意のユーザーを追跡できる可能性がある。

最後に、キーシステムの ユーザー制御用のユーザーインターフェイスが、HTTP セッション Cookie [COOKIES] または 永続ストレージ内のデータとは別にデータを提示する場合、 ユーザーは一方ではサイト承認を変更したりデータを削除したりし、他方ではそうしない可能性が高い。 これにより、サイトはさまざまな機能を相互の冗長バックアップとして使用できるようになり、 ユーザーが自身のプライバシーを保護しようとする試みを無効にする。

サイトおよびその他の第三者がユーザーを追跡する可能性に加えて、ユーザーエージェントの実装者、 CDM ベンダー、またはデバイスベンダーが、 ユーザーの活動または関心のプロファイル、たとえばユーザーが訪問する、この仕様で定義される API を 使用するサイトのプロファイルを構築する可能性がある。そのような追跡は、ウェブプラットフォームの 残りの部分によって提供されるプライバシー保護、とりわけオリジンの分離に関連するものを損なう。

特徴的な識別子などの識別子は、 CDM ベンダーによって運用または提供されるサーバーから、たとえば 個別化 プロセスを介して取得される場合がある。このプロセスには、クライアント識別子、 これには特徴的な永続的 識別子を含む、をサーバーに提供することが含まれる場合がある。 オリジンごとの識別子を生成するために、オリジンを表す値も提供される場合がある。

そのような実装では、CDM ベンダーが、訪問したオリジン数や 新しい識別子が必要となった回数など、ユーザーの活動を追跡できる可能性がある。 オリジンまたはオリジンと関連付け可能な値が 識別子要求で提供される場合、CDM ベンダーは、ユーザーまたはデバイスのユーザーが訪問したサイトを 追跡できる可能性がある。

次の節では、ユーザーの同意なしの追跡リスクを緩和し得る技法について説明する。

11.4.2 軽減策

特徴的な識別子または特徴的な永続的識別子を 使用しない

キーシステム実装は、可能な限り 特徴的な識別子および特徴的な永続的識別子を 使用することを避けるべきであり、それらが実装の堅牢性に意味のある形で 寄与する場合にのみ使用すべきである。特徴的な識別子および永続的識別子の使用を制限または 回避するを参照。

特徴的な 永続的識別子をアプリケーションに公開しない

実装は、特徴的な永続的 識別子を アプリケーションまたはオリジンに公開してはならない

特徴的な識別子を暗号化する

キーシステムメッセージ内の特徴的な識別子は、 タイムスタンプまたは nonce とともに暗号化されなければならず、 それによりキーシステム メッセージは常に 異なるものになる。これにより、キーシステム を完全にサポートするサーバーを除き、 追跡のためにキーシステムメッセージが 使用されることを防ぐ。識別子を暗号化するを参照。

特徴的な識別子 およびキーシステムに保存されたデータを Cookie / Web ストレージのように扱う

ユーザーエージェントは、特徴的な 識別子およびキーシステムによって保存されたデータの存在を、 HTTP セッション Cookie [COOKIES] と強く関連付ける方法で ユーザーに提示すべきであり、それを「すべてのデータを削除」に含め、 同じ UI 位置に提示すべきである。これにより、ユーザーがそのような識別子を 健全な疑念をもって見るよう促される可能性がある。ユーザーエージェントは、ユーザーが データの不完全な消去を避けるのを助けるべきである

オリジンごとの情報を無関係なエンティティに公開しない

オリジン、 またはオリジンと関連付け可能な値を、 個別化サーバーまたはオリジンに関連しないその他のエンティティに提供しない。 実装がそのようなプロセスを使用する場合は、個別化の節の要件および推奨事項に従う。

関連付け不可能な、オリジンごと・プロファイルごとの値および識別子を使用する

アプリケーションに公開されるすべての特徴的な値について、 実装は、各オリジン および 閲覧プロファイルごとに、 異なるアプリケーションによって 関連付け不可能な値を使用しなければならない8.4.1 オリジンごと・プロファイルごとの値を使用するを参照。

これは、特徴的な識別子を使用する実装にとって特に重要である。8.5.3 オリジンごと・プロファイルごとの識別子を使用するを参照。

オリジン固有かつ閲覧プロファイル固有のキーシステム ストレージを使用する

アプリケーションまたはライセンスサーバーから可視な形でメッセージまたは動作に影響を与える可能性がある、 CDM によって使用されるあらゆるデータは、 オリジン および 閲覧プロファイルによって分割されなければならず、 プライベートブラウジングセッションへ、またはそこから漏えいしてはならない。 これにはメモリ内データと永続化されたデータの両方が含まれる。具体的には、ただし網羅的ではないが、 セッションデータ、ライセンス、キー、およびオリジンごとの識別子は、 オリジン ごと、および閲覧プロファイルごとに分割されなければならない8.3.1 オリジン固有かつ閲覧プロファイル固有のキーシステムストレージを使用する および8.4.1 オリジンごと・プロファイルごとの値を使用するを参照。

特徴的な識別子を含む永続データの ユーザーによる削除を提供する

ユーザーエージェントは、キー システムによって保持される、特徴的な 識別子を含む任意の永続データを消去する能力をユーザーに提供しなければならない永続データを消去可能にするを参照。

保存されたデータを期限切れにする

ユーザーエージェントは、場合によってはユーザーによって設定された方法で、 特徴的な識別子および/またはその他の キーシステムデータを、一定期間後に自動的に削除してもよい

注記

たとえば、ユーザーエージェントは、そのようなデータをセッション専用ストレージとして保存し、 ユーザーがそれにアクセスできるすべての閲覧コンテキストを閉じた時点で そのデータを削除するよう設定できる。

これにより、サイトがユーザーを追跡する能力を制限できる。というのも、その場合、 サイト自体でユーザーが認証する場合(たとえば、購入を行う、またはサービスに サインインすることによる)にのみ、そのサイトは複数のセッションにわたってユーザーを 追跡できるからである。

ただし、ユーザーがそのような期限切れの含意を十分に理解していない場合、 これは、特に購入またはレンタルしたコンテンツへのユーザーのアクセスを 危険にさらす可能性もある。

第三者アクセスをブロックする

ユーザーエージェントは、キーシステムおよび/または機能へのアクセスを、 閲覧コンテキストのトップレベルのDocumentオリジンに由来する スクリプトに制限してもよい。たとえば、requestMediaKeySystemAccess() は、iframe 内で実行されている他のオリジンのページについて、特定の構成に対する 要求を拒否してもよい。

ユーザーエージェントは、特徴的な識別子または特徴的な永続的識別子を 使用する前に、ユーザーに十分に情報が提供されること、および/または明示的な同意を与えることを 保証しなければならない

そのような仕組みは、有効な使用が後続の悪意あるアクセスを可能にしないよう、 オリジンごとで なければならず、かつ閲覧プロファイルごとでなければならない

注記

この仕様で定義される API をセキュアコンテキストに制限することにより、 ネットワーク攻撃者が、認証されていないオリジンに付与された 権限を悪用できないことが保証される。永続化された同意の悪用を参照。

キーシステムまたはキーシステムによる識別子の使用を無効化する ユーザー制御を提供する

ユーザーエージェントは、 キーシステム が有効であるかどうか、および/またはキーシステムによる特徴的な識別子または特徴的な永続的識別子の 使用が有効であるかどうか(キーシステムによってサポートされる場合)について、 グローバルな制御をユーザーに提供すべきである。ユーザーエージェントは、ユーザーがデータの不完全な消去を避けるのを助けるべきである

キーシステムへのアクセスについて サイト固有のホワイトリスト化を要求する

ユーザーエージェントは、サイトが各キーシステム、および/または特定の機能を使用できるようになる前に、 ユーザーにアクセスを明示的に承認するよう要求してもよい。ユーザーエージェントは、 ユーザーがこの承認を一時的または永続的に取り消せるようにすべきである

共有ブラックリストを使用する

ユーザーエージェントは、ユーザーがオリジン および/またはキーシステムのブラックリストを共有できるようにしてもよい。これにより、コミュニティが協力してプライバシーを保護できるようになる。

注記

これらの提案は、この仕様で定義される API をユーザー追跡に自明に使用することを防ぐが、 それを完全に阻止するものではない。単一のオリジン内では、サイトはセッション中に ユーザーを追跡し続けることができ、その後、サイトが取得した任意の識別情報(名前、クレジットカード番号、 住所)とともに、このすべての情報を第三者に渡すことができる。第三者が複数のサイトと協力して そのような情報を取得し、かつ識別子が オリジンおよびプロファイルごとに一意でない場合、 プロファイルは依然として作成され得る。

11.5 ユーザーデバイス上に保存される情報

11.5.1 懸念

このセクションは非規範的である。

キーシステムはユーザーのデバイス上に情報を保存することがあり、 またはユーザーエージェントがキーシステムの代わりに情報を保存することがある。潜在的に、 これは同じデバイスの別のユーザーに対して、特定の キーシステムを使用した オリジン (すなわち訪問済みサイト)や、さらには キーシステムを使用して復号されたコンテンツを 含む、ユーザーに関する情報を明らかにし得る。

あるオリジンにより保存された情報が、別のオリジンに対する キーシステムの動作に影響する場合、あるサイトでユーザーが 訪問したサイトまたは視聴したコンテンツが、別の潜在的に悪意あるサイトに明らかになる可能性がある。

クライアントデバイス上のある閲覧プロファイルについて保存された情報が、 他の閲覧 プロファイル、またはブラウザーについての キーシステムの動作に影響する場合、 ある閲覧プロファイルで訪問されたサイトまたは 視聴されたコンテンツが、別の閲覧プロファイルにより明らかになったり、相関可能になったりする可能性があり、 異なるオペレーティングシステムのユーザーアカウントまたはブラウザーの場合さえ含まれる。

11.5.2 軽減策

これらの懸念を軽減する要件は、8.3 永続データで定義される。

11.6 データの不完全な消去

11.6.1 懸念

このセクションは非規範的である。

ユーザーが特徴的な識別子 および保存データを消去すること、および/またはキーシステムを無効化することによって 自身のプライバシーを保護しようとする試みは、そのようなデータおよび 機能のすべて、ならびに Cookie [COOKIES] およびその他の サイトデータが同時に消去および/または 無効化されない場合、無効にされる可能性がある。たとえば:

  • ユーザーが Cookie またはその他の永続ストレージを消去する際に、 特徴的な識別子およびキーシステムによって保存された データも消去しない場合、サイトはさまざまな機能を相互の冗長バックアップとして 使用することにより、その試みを無効にできる。

  • ユーザーが特徴的な 識別子を消去する際に、 キーシステムによって保存されたデータ、これには永続セッションを含む、 および Cookie やその他の 永続ストレージも消去しない場合、サイトは残りのデータを使用して 古い識別子と新しい識別子を関連付けることにより、その試みを無効にできる。

  • ユーザーがキーシステムを無効化する際、特に 特定のオリジンについて、 Cookie またはその他の永続ストレージも 消去しない場合、サイトは残りの機能を使用することにより、その試みを 無効にできる。

  • ユーザーがキーシステムを無効化し、その後 キーシステムを有効化することを決定した場合に、Cookie またはその他の 永続ストレージ、特徴的な 識別子、およびキー システムによって保存されたデータも消去しない場合、サイトは、 無効化前のデータを、キーシステムが 再び有効化された後のデータおよび動作と関連付けられる可能性がある。

11.6.2 軽減策

これらの懸念を軽減する推奨は、8.3 永続データで定義される。

11.7 プライベートブラウジングモード

ユーザーエージェントは、ユーザーの匿名性を保持すること、および/または閲覧活動の記録が クライアント上に永続化されないことを確保することを意図した動作モード(例: プライベートブラウジング)を サポートしてもよい。前のセクションで議論したプライバシー上の懸念は、そのようなモードを使用する ユーザーにとって特に重大な懸念となることがある。

そのようなモードをサポートするユーザーエージェント実装者は、これらのモードで キーシステムへのアクセスを無効化すべきかを慎重に検討すべきである (SHOULD)。例えば、そのようなモードは、 persistentState または distinctiveIdentifier をサポートまたは使用する MediaKeySystemAccess オブジェクトの作成を禁止してもよい (MAY)。これは CDM 実装の一部として、またはアプリケーションがそれらを "required" と示したためである。 実装がそのような作成を禁止しない場合、それらは、その使用を許可する前に、そのようなモードに 期待されるプライバシー特性への影響および潜在的な結果をユーザーに知らせるべきである (SHOULD)。

11.8 セキュアオリジンおよびトランスポート

この仕様で定義されるAPIはセキュアオリジンでのみサポートされ、前のセクションで議論された情報を 保護する。識別子は、識別子を暗号化するで指定されるように 追加で暗号化される。

アプリケーションは、それらが使用するサーバーを含め、CDM からのデータまたはメッセージを伴う、 または含むすべての通信について、セキュアトランスポートを使用すべきである (SHOULD)。これには、message イベントから渡される すべてのデータ、および update() へのすべてのデータを 含むが、これらに限定されない。

すべてのユーザーエージェントは、ユーザーエージェントまたはアプリケーションがセキュアオリジンおよび トランスポートを強制したい場合に、安全でないコンテンツまたはトランスポートへの露出を避けるため、 混合コンテンツ [MIXED-CONTENT] を適切に扱わなければならない (MUST)。

12. 適合性

非規範的として印付けされたセクションに加えて、この仕様におけるすべての作者向けガイドライン、図、 例、および注は非規範的である。この仕様におけるその他すべては規範的である。

この文書におけるキーワード MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHALL, SHALL NOT, SHOULD, and SHOULD NOT は、 ここに示されるようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] で説明されるように解釈される。

13.

このセクションは非規範的である。

このセクションは、提案された拡張を使用したさまざまなユースケースに対する例示的な解決策を含む。 これらは、これらのユースケースに対する唯一の解決策ではない。例では動画要素が使用されているが、 同じことはすべてのメディア要素に適用される。同期XHRを使用する場合など、場合によっては、 拡張に焦点を保つために例が簡略化されている。

13.1 ページ読み込み時にソースとキーが既知である場合(Clear Key)

この単純な例では、ソースファイルおよび平文ライセンスが ページ内にハードコードされている。作成されるセッションは常に1つだけである。

<script>
  function onLoad() {
    var video = document.getElementById('video');

    if (!video.mediaKeys) {
      navigator.requestMediaKeySystemAccess('org.w3.clearkey', [
        { initDataTypes: ['webm'],
          videoCapabilities: [{ contentType: 'video/webm; codecs="vp8"' }] }
      ]).then(
        function(keySystemAccess) {
          var promise = keySystemAccess.createMediaKeys();
          promise.catch(
            console.error.bind(console, 'Unable to create MediaKeys')
          );
          promise.then(
            function(createdMediaKeys) {
              return video.setMediaKeys(createdMediaKeys);
            }
          ).catch(
            console.error.bind(console, 'Unable to set MediaKeys')
          );
          promise.then(
            function(createdMediaKeys) {
              var te = new TextEncoder();
              var initData = te.encode( '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}');
              var keySession = createdMediaKeys.createSession();
              keySession.addEventListener("message", handleMessage, false);
              return keySession.generateRequest('keyids', initData);
            }
          ).catch(
            console.error.bind(console, 'Unable to create or initialize key session')
          );
        }
      );
    }
  }

  function handleMessage(event) {
    var keySession = event.target;
    var te = new TextEncoder();
    var license = te.encode('{"keys":[{"kty":"oct","k":"tQ0bJVWb6b0KPL6KtZIy_A","kid":"LwVHf8JLtPrv2GUXFW2v_A"}],"type":"temporary"}');
    keySession.update(license).catch(
      console.error.bind(console, 'update() failed')
    );
  }
</script>

<body onload='onLoad()'>
  <video src='foo.webm' autoplay id='video'></video>
</body>

13.2 サポートされるキーシステムを選択し、"encrypted" イベントからの初期化データを使用する

この例は、 requestMediaKeySystemAccess() メソッドを使用して、サポートされるキーシステムを選択し、その後 メディアデータからの 初期化データを使用して ライセンス要求を生成し、適切なライセンスサーバーへ送信する。サポートされるキーシステムの1つは serverCertificateを使用し、これは事前に提供される。

<script>
  var licenseUrl;
  var serverCertificate;

  // Returns a Promise<MediaKeys>.
  function createSupportedKeySystem() {
    someSystemOptions = [
     { initDataTypes: ['keyids', 'webm'],
       audioCapabilities: [
         { contentType: 'audio/webm; codecs="opus"' },
         { contentType: 'audio/webm; codecs="vorbis"' }
       ],
       videoCapabilities: [
         { contentType: 'video/webm; codecs="vp9"' },
         { contentType: 'video/webm; codecs="vp8"' }
       ]
     }
    ];
    clearKeyOptions = [
     { initDataTypes: ['keyids', 'webm'],
       audioCapabilities: [
         { contentType: 'audio/webm; codecs="opus"' },
         { contentType: 'audio/webm; codecs="vorbis"' }
       ],
       videoCapabilities: [
         { contentType: 'video/webm; codecs="vp9"',
           robustness: 'foo' },
         { contentType: 'video/webm; codecs="vp9"',
           robustness: 'bar' },
         { contentType: 'video/webm; codecs="vp8"',
           robustness: 'bar' },
       ]
     }
    ];

    return navigator.requestMediaKeySystemAccess('com.example.somesystem', someSystemOptions).then(
      function(keySystemAccess) {
        // Not shown:
        // 1. Use both attributes of keySystemAccess.getConfiguration().audioCapabilities[0]
        //    and both attributes of keySystemAccess.getConfiguration().videoCapabilities[0]
        //    to retrieve appropriate stream(s).
        // 2. Set video.src.

        licenseUrl = 'https://license.example.com/getkey';
        serverCertificate = new Uint8Array([ ... ]);
        return keySystemAccess.createMediaKeys();
      }
    ).catch(
      function(error) {
        // Try the next key system.
        navigator.requestMediaKeySystemAccess('org.w3.clearkey', clearKeyOptions).then(
          function(keySystemAccess) {
            // Not shown:
            // 1. Use keySystemAccess.getConfiguration().audioCapabilities[0].contentType
            //    and keySystemAccess.getConfiguration().videoCapabilities[0].contentType
            //    to retrieve appropriate stream(s).
            // 2. Set video.src.

            licenseUrl = 'https://license.example.com/clearkey/request';
            return keySystemAccess.createMediaKeys();
          }
        );
      }
    ).catch(
      console.error.bind(console, 'Unable to instantiate a key system supporting the required combinations')
    );
  }

  function handleInitData(event) {
    var video = event.target;
    if (video.mediaKeysObject === undefined) {
      video.mediaKeysObject = null; // Prevent entering this path again.
      video.pendingSessionData = []; // Will store all initData until the MediaKeys is ready.
      createSupportedKeySystem().then(
        function(createdMediaKeys) {
          video.mediaKeysObject = createdMediaKeys;

          if (serverCertificate)
            createdMediaKeys.setServerCertificate(serverCertificate);

          for (var i = 0; i < video.pendingSessionData.length; i++) {
            var data = video.pendingSessionData[i];
            makeNewRequest(video.mediaKeysObject, data.initDataType, data.initData);
          }
          video.pendingSessionData = [];

          return video.setMediaKeys(createdMediaKeys);
        }
      ).catch(
        console.error.bind(console, 'Failed to create and initialize a MediaKeys object')
      );
    }
    addSession(video, event.initDataType, event.initData);
  }

  function addSession(video, initDataType, initData) {
    if (video.mediaKeysObject) {
      makeNewRequest(video.mediaKeysObject, initDataType, initData);
    } else {
      video.pendingSessionData.push({initDataType: initDataType, initData: initData});
    }
  }

  function makeNewRequest(mediaKeys, initDataType, initData) {
    var keySession = mediaKeys.createSession();
    keySession.addEventListener("message", licenseRequestReady, false);
    keySession.generateRequest(initDataType, initData).catch(
      console.error.bind(console, 'Unable to create or initialize key session')
    );
  }

  function licenseRequestReady(event) {
    var request = event.message;

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.keySession = event.target;
    xmlhttp.open("POST", licenseUrl);
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4) {
        var license = new Uint8Array(xmlhttp.response);
        xmlhttp.keySession.update(license).catch(
          console.error.bind(console, 'update() failed')
        );
      }
    }
    xmlhttp.send(request);
  }
</script>

<video autoplay onencrypted='handleInitData(event)'></video>

13.3 メディアを読み込む前に MediaKeys を作成する

MediaKeys の初期化中にencryptedイベントを 処理する必要がなければ、初期化ははるかに単純になる。これは、 初期化データを別の方法で提供するか、 MediaKeys オブジェクトが作成された後にソースを設定することで実現できる。この例は後者を行う。

<script>
  var licenseUrl;
  var serverCertificate;
  var mediaKeys;

  // See the previous example for implementations of these functions.
  function createSupportedKeySystem() { ... }
  function makeNewRequest(mediaKeys, initDataType, initData) { ... }
  function licenseRequestReady(event) { ... }

  function handleInitData(event) {
    makeNewRequest(mediaKeys, event.initDataType, event.initData);
  }

  createSupportedKeySystem().then(
    function(createdMediaKeys) {
      mediaKeys = createdMediaKeys;
      var video = document.getElementById("v");
      video.src = 'foo.webm';
      if (serverCertificate)
        mediaKeys.setServerCertificate(serverCertificate);
      return video.setMediaKeys(mediaKeys);
    }
  ).catch(
    console.error.bind(console, 'Failed to create and initialize a MediaKeys object')
  );
</script>

<video id="v" autoplay onencrypted='handleInitData(event)'></video>

13.4 すべてのイベントを使用する

これは、すべてのイベントが使用されることを示す、より完全な例である。

handleMessage() は、複数回呼び出され得ることに注意すること。これには、 複数の往復が必要な場合の update() 呼び出しへの応答、 およびキーシステムがメッセージを送信する必要があるその他の任意の理由が含まれる。

<script>
  var licenseUrl;
  var serverCertificate;
  var mediaKeys;

  // See previous examples for implementations of these functions.
  // createSupportedKeySystem() additionally sets renewalUrl.
  function createSupportedKeySystem() { ... }
  function handleInitData(event) { ... }

  // This replaces the implementation in the previous example.
  function makeNewRequest(mediaKeys, initDataType, initData) {
    var keySession = mediaKeys.createSession();
    keySession.addEventListener('message', handleMessage, false);
    keySession.addEventListener('keystatuseschange', handlekeyStatusesChange, false);
    keySession.closed.then(
      function(reason) {
        console.log('Session', this.sessionId, 'closed, reason', reason);
      }.bind(keySession)
    );
    keySession.generateRequest(initDataType, initData).catch(
      console.error.bind(console, 'Unable to create or initialize key session')
    );
  }

  function handleMessageResponse(keySession, response) {
    var license = new Uint8Array(response);
    keySession.update(license).catch(
      function(err) {
        console.error('update() failed: ' + err);
      }
    );
  }

  function sendMessage(type, message, keySession) {
    var url = licenseUrl;
    if (type == "license-renewal")
      url = renewalUrl;
    xmlhttp = new XMLHttpRequest();
    xmlhttp.keySession = keySession;
    xmlhttp.open('POST', url);
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4)
        handleMessageResponse(xmlhttp.keySession, xmlhttp.response);
    }
    xmlhttp.send(message);
  }

  function handleMessage(event) {
    sendMessage(event.messageType, event.message, event.target);
  }

  function handlekeyStatusesChange(event) {
    // Evaluate the current state using one of the map-like methods exposed by
    // event.target.keyStatuses.
    // For example:
    event.target.keyStatuses.forEach(function(status, keyId) {
      switch (status) {
        case "usable":
          break;
        case "expired":
          // Report an expired key.
          break;
        case "status-pending":
          // The status is not yet known. Consider the key unusable until the status is updated.
          break;
        default:
          // Do something with |keyId| and |status|.
      }
    })
  }

  createSupportedKeySystem().then(
    function(createdMediaKeys) {
      mediaKeys = createdMediaKeys;
      var video = document.getElementById("v");
      video.src = 'foo.webm';
      if (serverCertificate)
        mediaKeys.setServerCertificate(serverCertificate);
      return video.setMediaKeys(mediaKeys);
    }
  ).catch(
    console.error.bind(console, 'Failed to create and initialize a MediaKeys object')
  );
</script>

<video id="v" autoplay onencrypted='handleInitData(event)'></video>

13.5 保存済みライセンス

この例は、将来の使用のために永続ライセンスを要求して保存する。また、後でライセンスを取得するための 関数と、それを破棄するための関数も提供する。

<script>
  var licenseUrl;
  var serverCertificate;
  var mediaKeys;

  // See the previous examples for implementations of these functions.
  // createSupportedKeySystem() additionally sets persistentState: "required" in each options dictionary.
  function createSupportedKeySystem() { ... }
  function sendMessage(message, keySession) { ... }
  function handleMessage(event) { ... }

  // Called if the application does not have a stored sessionId for the media resource.
  function makeNewRequest(mediaKeys, initDataType, initData) {
    var keySession = mediaKeys.createSession("persistent-license");
    keySession.addEventListener('message', handleMessage, false);
    keySession.closed.then(
      function(reason) {
        console.log('Session', this.sessionId, 'closed, reason', reason);
      }.bind(keySession)
    );
    keySession.generateRequest(initDataType, initData).then(
      function() {
        // Store this.sessionId in the application.
      }.bind(keySession)
    ).catch(
      console.error.bind(console, 'Unable to request a persistent license')
    );
  }

  // Called if the application has a stored sessionId for the media resource.
  function loadStoredSession(mediaKeys, sessionId) {
    var keySession = mediaKeys.createSession("persistent-license");
    keySession.addEventListener('message', handleMessage, false);
    keySession.closed.then(
      function(reason) {
        console.log('Session', this.sessionId, 'closed, reason', reason);
      }.bind(keySession)
    );
    keySession.load(sessionId).then(
      function(loaded) {
        if (!loaded) {
          console.error('No stored session with the ID ' + sessionId + ' was found.');
          // The application should remove its record of |sessionId|.
          return;
        }
      }
    ).catch(
      console.error.bind(console, 'Unable to load or initialize the stored session with the ID ' + sessionId)
    );
  }

  // Called when the application wants to stop using the session without removing the stored license.
  function closeSession(keySession) {
    keySession.close();
  }

  // Called when the application wants to remove the stored license.
  // The stored session data has not been completely removed until the promise returned by remove() is fulfilled.
  // The remove() call may initiate a series of messages to/from the server that must be completed before this occurs.
  function removeStoredSession(keySession) {
    keySession.remove().then(
      function() {
        console.log('Session ' + this.sessionId + ' removed');
        // The application should remove its record of this.sessionId.
      }.bind(keySession)
    ).catch(
      console.error.bind(console, 'Failed to remove the session')
    );
  }

  // This replaces the implementation in the previous example.
  function handleMessageResponse(keySession, response) {
    var license = new Uint8Array(response);
    keySession.update(license).then(
      function() {
        // If this was the last required message from the server, the license is
        // now stored. Update the application state as appropriate.
      }
    ).catch(
      console.error.bind(console, 'update() failed')
    );
  }

  createSupportedKeySystem().then(
    function(createdMediaKeys) {
      mediaKeys = createdMediaKeys;
      var video = document.getElementById("v");
      if (serverCertificate)
        mediaKeys.setServerCertificate(serverCertificate);
      return video.setMediaKeys(mediaKeys);
    }
  ).catch(
    console.error.bind(console, 'Failed to create and initialize a MediaKeys object')
  );
</script>

<video id='v' src='foo.webm' autoplay></video>

13.6 HDCPポリシー付きメディアを事前取得する

あるメディアがライセンス内にHDCPポリシーを持つ場合、アプリケーションは事前取得する前に そのバージョンを確認できる。

const status = await video.mediaKeys.getStatusForPolicy({
  minHdcpVersion: '1.4'
});

if (status === 'usable') {
  // Pre-fetch HD content.
} else {  // 'output-restricted'
  // Pre-fetch SD content.
}

14. 謝辞

編集者は、この仕様への貢献について、Aaron Colwell、Alex Russell、Anne van Kesteren、Bob Lund、 Boris Zbarsky、Chris Needham、Chris Pearce、David Singer、Domenic Denicola、Frank Galligan、 Glenn Adams、Henri Sivonen、Jer Noble、Joe Steele、Joey Parrish、John Simmons、Mark Vickers、Pavel Pergamenshchik、Philip Jägenstedt、Pierre Lemieux、Robert O'Callahan、Ryan Sleevi、Steve Heffernan、Steven Robertson、Theresa O'Connor、Thomás Inskip、Travis Leithead、 および Xiaohan Wang に感謝する。また、メーリングリストおよび課題への参加を含め、 仕様に貢献した多くの他の方々にも感謝する。

A. 参考文献

A.1 規範的参考文献

[COOKIES]
HTTP 状態管理メカニズム. A. Barth. IETF. 2011年4月. 標準化提案. URL: https://httpwg.org/specs/rfc6265.html
[dom]
DOM 標準. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript 言語仕様. Ecma International. URL: https://tc39.es/ecma262/multipage/
[EME-INITDATA-KEYIDS]
"keyids" 初期化データ 形式. Joey Parrish; Greg Freedman. W3C. 2024年8月20日. W3C Working Group Note. URL: https://www.w3.org/TR/eme-initdata-keyids/
[EME-INITDATA-REGISTRY]
暗号化メディア拡張 初期化データ形式レジストリ. Joey Parrish; Greg Freedman. W3C. 2026年5月7日 2026. DRY. URL: https://www.w3.org/TR/eme-initdata-registry/
[ENCODING]
Encoding 標準. Anne van Kesteren. WHATWG. Living Standard. URL: https://encoding.spec.whatwg.org/
[HTML]
HTML 標準. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[Infra]
Infra 標準. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[mimesniff]
MIME Sniffing 標準. Gordon P. Hemsley. WHATWG. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[MIXED-CONTENT]
混合コンテンツ. Emily Stark; Mike West; Carlos IbarraLopez. W3C. 2023年2月23日. CRD. URL: https://www.w3.org/TR/mixed-content/
[PERMISSIONS-POLICY]
権限ポリシー. Ian Clelland. W3C. 2025年10月6日. W3C 作業草案. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
要求レベルを示すために RFC で使用する キーワード. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC6381]
"Bucket" メディアタイプの 'Codecs' および 'Profiles' パラメーター. R. Gellens; D. Singer; P. Frojdh. IETF. 2011年8月. 標準化提案. URL: https://www.rfc-editor.org/rfc/rfc6381
[RFC7517]
JSON Web Key (JWK). M. Jones. IETF. 2015年5月. 標準化提案. URL: https://www.rfc-editor.org/rfc/rfc7517
[RFC8174]
RFC 2119 キーワードにおける大文字と小文字の 曖昧性. B. Leiba. IETF. 2017年5月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBIDL]
Web IDL 標準. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

A.2 参考情報の参考文献

[CENC]
ISO/IEC 23001-7:2016, 情報技術 — MPEG システム技術 — Part 7: ISO Base Media File Format ファイルにおける共通 暗号化. ISO/IEC. 国際標準. URL: https://www.iso.org/obp/ui/#iso:std:iso-iec:23001:-7:ed-3:v1
[EME-HDCP-VERSION-REGISTRY]
暗号化メディア拡張 HDCP バージョンレジストリ. Joey Parrish; Greg Freedman. W3C. 2026年5月7日. DRY. URL: https://www.w3.org/TR/eme-hdcp-version-registry/
[EME-STREAM-REGISTRY]
暗号化メディア拡張ストリーム形式 レジストリ. Joey Parrish; Greg Freedman. W3C. 2026年5月7日. DRY. URL: https://www.w3.org/TR/eme-stream-registry/
[MEDIA-SOURCE]
Media Source Extensions™. Jean-Yves Avenard; Mark Watson. W3C. 2025年11月4日. W3C 作業草案. URL: https://www.w3.org/TR/media-source-2/
[RFC6838]
メディアタイプ仕様および登録 手続き. N. Freed; J. Klensin; T. Hansen. IETF. 2013年1月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc6838
[RFC7515]
JSON Web Signature (JWS). M. Jones; J. Bradley; N. Sakimura. IETF. 2015年5月. 標準化提案. URL: https://www.rfc-editor.org/rfc/rfc7515
[webaudio]
Web Audio API 1.1. Paul Adenot; Hongchan Choi. W3C. 2024年11月5日. FPWD. URL: https://www.w3.org/TR/webaudio-1.1/