暗号化メディア拡張

W3C 作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-encrypted-media-2-20260707/
最新公開バージョン:
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/
編集者:
Xiaohan Wang (Google LLC)
Greg Freedman (Netflix Inc.)
元編集者:
Joey Parrish (Google LLC) (Until June 2026)
Mark Watson (Netflix Inc.) (Until September 2019)
David Dorwin (Google Inc.) (Until September 2017)
Jerry Smith (Microsoft Corporation) (Until September 2017)
Adrian Bateman (Microsoft Corporation) (Until May 2014)
フィードバック:
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オブジェクトを識別するために 使用できる。

ユーザーエージェントおよびCDMが新しいセッションを 正常に作成するたびに、新しいセッションIDが生成される。

各セッションIDは、それが作成された閲覧コンテキスト内で一意でなければならない(SHALL)。 永続セッション型か?アルゴリズムが trueを返すセッション型については、セッションIDは、閲覧セッションをまたいで 時間的にオリジン内で 一意でなければならない(MUST)。

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

キー

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

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

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

復号に 使用可能

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

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

キーID

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

既知キー

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

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

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

ライセンス

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

初期化データ
Best Practice 2: 初期化データを 生成する際は、コンテンツを復号するために必要な各 キーを一意に識別すること。

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

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

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

Encrypted Media Extensions 初期化データ形式レジストリーは、初期化データ型 文字列から各形式の仕様への対応付けを提供する。

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

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

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

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

関連付け可能な値

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

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

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

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

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

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

対照的に、暗号的に強い不可逆ハッシュ関数を介する場合など、完全に無関係または 暗号的に区別される2つの値は、 関連付け不能である。

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

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

識別性のある値

識別性のある値とは、大規模なユーザー集団またはクライアントデバイス集団で共有されていない 値、データの一部、データの一部を保持していることの含意、または観測可能な動作もしくは タイミングである。識別性のある値は、メモリ内に存在する場合もあれば、永続化される場合もある。

識別性のある値の例には、以下が含まれるが、これらに限定されない。

識別性のある値は通常、ユーザーまたはクライアントデバイスに一意であるが、識別性を持つために 厳密に一意である必要はない。たとえば、少数のユーザー間で共有される値でも、 識別性を持つ場合がある。

永続識別子

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

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

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

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

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

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

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

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

識別性のある永続 識別子とは、永続識別子であって 識別性のあるものである。

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

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

識別性のある永続識別子は、(この仕様の範囲内で)派生または生成されるものではないため、 識別性のある識別子ではない

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

識別性のある識別子

識別性のある識別子とは、不透明または暗号化された形を含む値であって、クライアント外部の 任意の主体が、ユーザーがWebプラットフォーム上で想定しうる範囲(例:Cookieおよび その他のサイトデータ)を超えて値を相関付けまたは関連付けることが可能なものである。 たとえば、a) オリジン、 b) 閲覧プロファイル、または c) 閲覧セッションをまたいで、アプリケーション以外の主体によって 関連付け可能な値、あるいは ユーザーが閲覧データを消去してプライバシーを保護しようとした後でも、そのような関連付けを ユーザーが容易に断ち切れない値などである。特に、個別化サーバーなどの中央サーバーが、値を オリジン間で関連付けることが可能である場合、その値は識別性のある識別子である。 たとえば、個別化要求に共通の値が含まれていた場合、 または個別化要求で提供された値が、閲覧データの消去の試み後であっても そのようなサーバーによって関連付け可能である場合などである。 これが生じうる原因には、個別化プロセスにおける 識別性のある 永続識別子の使用が含まれる。

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

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

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

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

  • それが識別性のあるものである。

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

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

  • それが以下の1つ以上の性質を持つ。

    アプリケーションに公開される値について、規範的に禁止されるその他の懸念される性質には 以下が含まれる。

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

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

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

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

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

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

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

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

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

識別性のある識別子は通常、それを生成した主体によって関連付け可能であるが、 アプリケーションによって関連付け不能でなければならない (MUST)。言い換えると、そのような相関付けまたは関連付けは、識別性のある 識別子の値をもともと生成した主体、たとえば 個別化サーバーによってのみ可能である。 識別性のある永続識別子にアクセスできる 主体は、この能力をアプリケーションに公開してはならない(MUST NOT)。それは結果として得られる 識別性のある識別子をアプリケーションによって 関連付け可能にしてしまうためであり、またそのような相関を他の主体または第三者に 露出しないよう注意すべきである(SHOULD)。

識別性のある識別子の例には、以下が含まれるが、これらに限定されない。

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

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

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

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

  • 最初の値が直接公開されない場合でも、公開される別の値を派生するために使用される そのような値。

  • 別の識別性のある識別子から派生した値。

  • 識別性のある永続 識別子とともに(例:個別化)サーバーに報告されたランダム値、 または識別性のある永続 識別子を提供した後にそのようなサーバーによって提供された値。

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

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

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

識別性のある識別子ではないものの例。

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

  • 1つのセッションでのみ使用される、一意なノンスまたは一時鍵。

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

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

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

    • その値の生成に識別性のある 永続識別子または識別性のある識別子が関与していない。

    • それがシステムからの入力を用いずに生成されたランダム値である。

    • それが、別の識別性のある識別子を使用または認識することなくサーバーから 提供された値である。

識別性のある識別子および 識別性のある永続 識別子の使用

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

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

実装、構成、インスタンス、またはオブジェクトは、 識別性のある識別子を使用する、および/または 識別性のある 永続識別子を使用する場合、 識別性のある識別子または識別性のある永続識別子を使用する

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

クロスオリジン制限

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

混在 コンテンツ制限

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

時刻

時刻は、 ECMAScript言語 仕様で表されるものと同等でなければならない(MUST)。

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

時刻は一般にミリ秒精度の瞬間を表すが、それだけでは十分な定義ではない。 ECMAScript言語 仕様のTime Values and Time Range節は、その他の重要な要件を追加している。

期限時刻

その後、キーが復号に使用可能ではなくなる 時刻

閲覧プロファイル

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

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

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、既定値は ""
MediaKeySystemConfigurationgetConfiguration() メソッドから返される MediaKeySystemAccess 内で保持される任意のラベル。
initDataTypes の型は sequence<DOMString>、 既定値は []
サポートされる 初期化データ型 名のリスト。このオブジェクトの 初期化データ型 能力は、リストが空である場合、または(アルゴリズムによって判定されるように) 他のすべてのメンバーとともにサポートされる 1 つ以上の値を含む場合に、 サポートされているとみなされる。シーケンス内の値は空文字列であっては ならない
audioCapabilities の型は sequence<MediaKeySystemMediaCapability>、 既定値は []
サポートされる音声の型と能力のペアのリスト。このオブジェクトの音声能力は、 リストが空である場合、または(アルゴリズムによって判定されるように) 他のすべてのメンバーとともにサポートされる 1 つ以上の値を含む場合に、 サポートされているとみなされる。値の間に競合がある場合は、先に現れる値が 選択される。空のリストは、音声能力がサポートされていないことを示す。 この場合、 videoCapabilities 要素は空であってはならない
videoCapabilities の型は sequence<MediaKeySystemMediaCapability>、 既定値は []
サポートされる動画の型と能力のペアのリスト。このオブジェクトの動画能力は、 リストが空である場合、または(アルゴリズムによって判定されるように) 他のすべてのメンバーとともにサポートされる 1 つ以上の値を含む場合に、 サポートされているとみなされる。値の間に競合がある場合は、先に現れる値が 選択される。空のリストは、動画能力がサポートされていないことを示す。 この場合、 audioCapabilities 要素は空であってはならない
distinctiveIdentifier の型は MediaKeysRequirement、 既定値は "optional"
固有識別子 の使用が必要かどうか。

このメンバーが「not-allowed」の場合、 実装は、この構成から作成された任意のオブジェクトに関連付けられたどの操作についても、 固有識別子または固有の永続識別子を使用 してはならない

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

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

このメンバーの目的上、永続状態には、 Key System 実装によって制御される永続的な一意識別子 (固有識別子) は含まれない。 distinctiveIdentifier は、この要件を独立して反映する。

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

temporary」 セッションについては、状態を保存する必要性および能力は Key System 実装固有であり、使用される機能によって 異なる場合がある。

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

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

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

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

この辞書は、状態またはデータを 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

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

アプリケーションはそのようなストレージの管理を心配する必要はない。この セッション型のサポートは必須である。

persistent-license

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

この型のセッションは、このオブジェクトを作成した MediaKeySystemAccess オブジェクトに関連付けられた 構成の persistentState 値が "required" である場合にのみ 作成できる。セッションは、セッション IDを介して、update() が 正常に呼び出された後に読み込めなければならない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. truepromise を解決する。

  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オリジンだけが アクセスできるように、常に保存しなければならない。加えて、ユーザーエージェントは、そのデータを現在の 閲覧プロファイルにのみ アクセス可能にしなければならないユーザーエージェントは、他の 閲覧プロファイル、ユーザーエージェント、およびアプリケーションが保存されたデータにアクセスすることを 許可してはならないユーザーデバイスに保存される情報を参照。

永続ストレージをサポートする際の追加の考慮事項については、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 は、そのオブジェクトに関連付けられたキーセッションを閉じなければならない

注記

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

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

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

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

プロミスを拒否する場合、アルゴリズムの以降の手順は常に中止される。

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

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

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

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

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)。

注記

マップのエントリーとその値は、イベントループが回るたびに更新される可能性がある。 マップが不整合になったり部分的に更新されたりすることはないが、アクセスの間に イベントループが回った場合、アクセス間で変更される可能性がある。キー ID は、 load() または update() 呼び出しの 結果として追加される可能性がある。キー ID は、既存のキーに関する知識を削除する (または既存のキーの集合を新しい集合で置き換える)update() 呼び出しの 結果として削除される可能性がある。キー ID は、有効期限切れなどにより使用不能になった場合でも 削除されない。その代わり、そのようなキーには "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 で reject された promise を返す。

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

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

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

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

  6. このオブジェクトの cdm implementation 値によって表される Key System 実装が、 initDataTypeInitialization Data Typeとしてサポートしていない場合、 NotSupportedError で reject された promise を返す。文字列比較は大小文字を区別する。

  7. init data を、 initData によって保持されているバイトのコピーを取得する 結果とする。

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

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

  10. 次の手順を並行して実行する:

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

    2. sanitized init data を、 init data の検証済みかつサニタイズ済みの版とする。

      ユーザーエージェントは、Initialization DataCDM に渡す前に、 徹底的に検証し MUST。これには、フィールドの長さと値が 妥当であることの検証、値が妥当な制限内にあることの検証、および無関係な、 サポートされていない、または未知のデータやフィールドの除去が含まれる。 ユーザーエージェントが Initialization Data を事前解析、 サニタイズ、かつ/または完全にサニタイズ済みの版として生成することが RECOMMENDEDinitDataType によって指定される Initialization Data 形式が複数のエントリーをサポートする場合、 ユーザーエージェントは CDM に不要なエントリーを削除し SHOULD。ユーザーエージェントは Initialization Data 内のエントリーを並べ替えてはならない MUST NOT

    3. 先行する手順が失敗した場合、promise を、新しく作成された TypeError で reject する。

    4. sanitized init data が空である場合、promiseNotSupportedError で reject する。

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

    6. message を null とする。

    7. message type を null とする。

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

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

      1. sanitized init datacdm によってサポートされていない場合、 promiseNotSupportedError で reject する。

      2. 次のリストから、session type の値に対する手順に従う:

        "temporary"

        requested license typeを、一時的な 永続化不能 ライセンスとする。CDMは、 ライセンスに関連する情報を永続化してはならず、また永続化を要求しては ならない(MUST NOT)。

        "persistent-license"

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

      3. session id を一意の Session ID 文字列とする。

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

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

          CDM である cdm は、 sanitized init data を介して提供されていない、 media data を含むストリーム固有のデータを使用してはならない MUST NOT

          CDM である cdm は、この時点でセッション ID を含む セッションデータを保存すべきではない SHOULD NOTSession Storage and Persistence を参照。

        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 type を、message の型、 すなわち "license-request" または "individualization-request" を反映するものとする。

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

      1. 先行する手順のいずれかがリソース不足により失敗した場合、 promiseQuotaExceededError で reject する。

      2. 先行する手順のいずれかがその他の理由で失敗した場合、 promise を、その name が適切な error name である新しい DOMException で reject する。

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

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

      5. promiseundefined で resolve する。

      6. session に対して Queue a "message" Event アルゴリズムを実行し、message typemessage を提供する。

  11. promise を返す。

load()

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

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

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

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

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

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

  5. このオブジェクトの session type に対して Is persistent session type? アルゴリズムを実行した結果が false である場合、新しく作成された TypeError で reject された promise を返す。

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

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

  8. 次の手順を並行して実行する:

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

      注記

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

    2. 先行する手順が失敗した場合、または sanitized session ID が空である場合、 promise を、新しく作成された TypeError で reject する。

    3. このオブジェクトの Document 内に、 closed でない MediaKeySession オブジェクトであって、 その sessionId 属性が sanitized session ID であるものが存在する場合、 promiseQuotaExceededError で reject する。

      注記

      言い換えれば、この閲覧コンテキスト内で、この 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 で resolve し、 このアルゴリズムの並行手順を中止する。

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

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

      4. いずれかの Document 内に、closed でない MediaKeySession オブジェクトであって session data を表すものが存在する場合、promiseQuotaExceededError で reject する。

        注記

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

      5. session data を読み込む。

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

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

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

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

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

      1. 先行する手順のいずれかが失敗した場合、promise を適切な error name で reject する。

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

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

      4. 読み込まれたセッションがいずれかのキーに関する情報を含む場合 (known keys がある場合)、 session に対して Update Key Statuses アルゴリズムを実行し、各キーの key ID と、適切な MediaKeyStatus を提供する。

        キーの状態を確実に決定するために追加処理が必要である場合は、 "status-pending" を使用する。1 つ以上のキーに対する追加処理が完了したら、 実際の状態を用いて Update Key Statuses アルゴリズムを再度実行する。

      5. session に対して Update Expiration アルゴリズムを実行し、 expiration time を提供する。

      6. promisetrue で resolve する。

      7. message が null でない場合、session に対して Queue a "message" Event アルゴリズムを実行し、message typemessage を提供する。

  9. promise を返す。

update()

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

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

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

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

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

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

  4. response copy を、 response によって保持されているバイトのコピーを取得する 結果とする。

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

  6. 次の手順を並行して実行する:

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

      注記

      ユーザーエージェントは、response を CDM に渡す前に徹底的に検証すべきである。 これには、値が妥当な制限内にあることの検証、無関係なデータやフィールドの除去、 事前解析、サニタイズ、かつ/または完全にサニタイズ済みの版の生成が含まれ得る。 ユーザーエージェントは、フィールドの長さと値が妥当であることを確認すべきである。 未知のフィールドは reject されるか削除されるべきである。

    2. 先行する手順が失敗した場合、または sanitized response が空である場合、 promise を、新しく作成された TypeError で reject する。

    3. message を null とする。

    4. message type を null とする。

    5. session closed を false とする。

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

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

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

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

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

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

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

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

        promise を、新しく作成された TypeError で reject する。

        Session Storage and Persistence も参照。

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

        注記

        sanitized response がキーかつ/または関連データを含む場合、 cdm は、おそらくキーおよび関連データをキー ID によって インデックス付けして(メモリ内に)保存する。

        注記

        セッション内の置換アルゴリズムは Key System 依存である。

        注記

        CDM 実装が、MediaKeySession オブジェクトごとの標準かつ合理的に高いキーの最小数を、標準の置換アルゴリズムとともにサポートし、 さらに標準かつ合理的に高い数の MediaKeySession オブジェクトをサポートすることが RECOMMENDED。 これにより、合理的な数のキー回転アルゴリズムをユーザーエージェント間で 実装できるようになり、同じ要素内のさまざまなストリーム (たとえば、適応ストリーム、さまざまなオーディオトラックおよびビデオ トラック)が異なるキーを使用するユースケースで、再生中断の可能性を 低減できる。

        sanitized responserecord of license destruction の確認応答を含み、かつ sessionType が "persistent-license" である場合

        次の手順を実行する:

        1. key session を閉じ、 このオブジェクトに関連付けられた保存済みセッションデータを すべて消去する。これには sessionId および record of license destruction が含まれる。

          注記

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

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

        そうでない場合
        セッションデータを保存せずに sanitized response を処理する。
        注記

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

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

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

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

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

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

        このオブジェクトに対して Session Closed アルゴリズムを理由 "release-acknowledged" で実行する。

        そうでない場合:

        次の手順を実行する:

        1. このオブジェクトについて CDMknown なキーの集合が 変更された場合、またはいずれかのキーの状態が変更された場合、 session に対して Update Key Statuses アルゴリズムを実行し、各既知のキーの key ID と、適切な MediaKeyStatus を提供する。

          キーの状態を確実に決定するために追加処理が必要である場合は、 "status-pending" を使用する。1 つ以上のキーに対する追加処理が完了したら、 実際の状態を用いて Update Key Statuses アルゴリズムを再度実行する。

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

        3. 先行する手順のいずれかが失敗した場合、 promise を、その name が適切な error name である新しい DOMException で reject する。

        4. message が null でない場合、 session に対して Queue a "message" Event アルゴリズムを実行し、 message typemessage を提供する。

      2. promiseundefined で resolve する。

  7. promise を返す。

close()

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

注記

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

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

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

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

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

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

  5. 次の手順を並行して実行する:

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

    2. cdm を使用して、このオブジェクトに関連付けられた key session を閉じる。

      注記

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

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

      1. promiseundefined で resolve する。

      2. このオブジェクトに対して Session Closed アルゴリズムを理由 "closed-by-application" で実行する。

  6. promise を返す。

remove()

セッションに関連付けられたすべてのライセンスおよびキーを削除する。 persistent session types については、 release message acknowledgement が update() によって処理されると、各セッション型に対して定義されるとおり、その他のセッションデータが 消去される。

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

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

  2. このオブジェクトの callable 値が false である場合、 InvalidStateError で reject された 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 を、 このオブジェクトによって表されるライセンスの record of license destruction とする。

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

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

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

      1. session に対して Update Key Statuses アルゴリズムを実行し、セッション内のすべての key ID と、 それぞれに対する "released" MediaKeyStatus 値を提供する。

      2. session に対して Update Expiration アルゴリズムを実行し、 NaN を提供する。

      3. 先行する手順のいずれかが失敗した場合、promise を、その name が 適切な error name である新しい DOMException で reject する。

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

      5. promiseundefined で resolve する。

      6. messagenull でない場合、 session に対して Queue a "message" Event アルゴリズムを実行し、 message typemessage を提供する。

  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 属性の内容が、その属性への既存の参照を無効化することなく置き換えられることである。 この置換は、スクリプトの観点からはアトミックである。すなわち、 スクリプトが部分的に設定されたシーケンスを目にすることは決してない。

  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 セッション 閉鎖

Session Closed アルゴリズムは、MediaKeySession の状態を、key sessionCDM によって閉じられた後に更新する。このアルゴリズムを実行する要求には、 対象の MediaKeySession オブジェクト および MediaKeySessionClosedReason が含まれる。

注記

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

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

注記

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

他のセッション内のキーは、たとえ重複するキー ID を持っていても、 影響を受けてはならないMUST

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

次の手順を実行する:

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

  2. promise を、sessionclosed 属性とする。

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

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

  5. session に対して Update Key Statuses アルゴリズムを実行し、 空シーケンスを提供する。

  6. session に対して Update Expiration アルゴリズムを 実行し、 NaN を提供する。

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

6.6.5 CDM状態変化の監視

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

注記

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

注記

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

次の手順を実行する:

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

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

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

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

    2. Queue a "message" Event アルゴリズムを実行し、sessionmessage type、および message を渡す。

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

    1. statuses を、session既知の 各キーについて 1 組を含む、キー ID と MediaKeyStatus 値のペアのリストとする。

    2. Update Key Statuses アルゴリズムを実行し、sessionstatuses を渡す。

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

    1. expiration time を、session の新しい有効期限時刻とする。

    2. Update Expiration アルゴリズムを実行し、sessionexpiration time を渡す。

  6. cdmsession を閉じた場合、session に対して、 適切な MediaKeySessionClosedReason 値を用いて Session Closed アルゴリズムを実行するようにタスクを キューに入れる

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

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

6.7 例外

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

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

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

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

次の要件は、Storage and Persistence の要件に加えて適用される。

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

このセクションの残りは、Is persistent session type? アルゴリズムが true を返すセッション型に適用される。

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

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

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

Is persistent session type? アルゴリズムが true を返す型を使用してセッションを作成するアプリケーションは、後で、まず remove() を使用して削除処理を開始し、 その後、メッセージ交換を伴う可能性のある削除処理が正常に完了することを保証することによって、 保存されたデータを削除すべきである SHOULDCDM も適宜セッションを削除してもよい MAY が、アプリケーションは これに依存すべきではない SHOULD NOT

永続ストレージをサポートする際の追加の考慮事項については、10. Security および 11. Privacy を参照。

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 の reject をもたらす。

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

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

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

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

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

  5. 次の手順を並行して実行する:

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

      • mediaKeys が null でなく、

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

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

      ならば、次の手順を実行する:

      1. 次の手順を実行するようにタスクをキューに入れる

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

        2. promiseQuotaExceededError で reject する。

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

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

      1. ユーザーエージェントまたは CDM が 関連付けの削除をサポートしていない場合、次の手順を実行する:

        1. 次の手順を実行するようにタスクをキューに入れる

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

          2. promiseNotSupportedError で reject する。

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

      2. 関連付けを現在削除できない場合、次の手順を実行する:

        注記

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

        1. 次の手順を実行するようにタスクをキューに入れる

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

          2. promiseInvalidStateError で reject する。

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

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

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

        1. 次の手順を実行するようにタスクをキューに入れる

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

          2. promise を適切な error name で reject する。

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

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

      1. mediaKeys によって表される CDM インスタンスを、 メディア データを復号するためにメディア要素に関連付ける。

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

        1. 次の手順を実行するようにタスクをキューに入れる

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

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

          3. promise を、その name が適切な error name である新しい DOMException で reject する。

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

    4. 次の手順を実行するようにタスクをキューに入れる

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

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

      3. promiseundefined で resolve する。

      4. mediaKeys が null でない場合、メディア要素に対して Attempt to Resume Playback If Necessary アルゴリズムを実行する。

  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 を初期化データとする。

  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. 実装要件

このセクションは、ユーザーエージェントとKey Systems の双方について、CDM およびサーバーを含む、 アルゴリズムでは明示的に扱われていない可能性がある実装要件を定義する。 ここおよび仕様全体の要件は、CDM がユーザーエージェントから分離されているか、その一部であるかにかかわらず、 すべての実装に適用される。

8.1 CDM の制約

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

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

8.2 メッセージおよび通信

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

8.3 永続データ

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

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 は、暗号化キーがその Key System に対する有効なサーバーに 属していることを検証しなければならない MUST。アプリケーションに公開される 識別子については、これは サーバー証明書を使用して実装されてもよい MAY

サーバーは、送信元である CDM 以外のいかなるエンティティにも、 Distinctive Identifier を公開してはならない MUST NOT

注記

具体的には、それはアプリケーションに提供されるべきではなく、また 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 直接個別化

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

注記

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

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

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

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

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

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

  • すべての Distinctive Identifiers および Distinctive Permanent Identifiers を暗号化しなければならない MUST

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

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

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 攻撃および脆弱性

ユーザーエージェントは、ユーザーが安全にウェブを閲覧できる方法を提供する責任を負う。この 責任は、第三者からの機能を含め、ユーザーエージェントによって使用されるあらゆる機能に適用される。 ユーザーエージェントの実装者は、Key System の実装者から十分な 情報を取得し、Key System と統合することの セキュリティ上の影響を適切に評価できるようにしなければならない MUST。 ユーザーエージェントの実装者は、CDM 実装が、ユーザーエージェントがユーザーの セキュリティを提供するために十分な制御を提供し、かつ/またはサポートすることを 保証しなければならない MUST。ユーザーエージェントの実装者は、CDM 実装が、セキュリティ脆弱性が発生した場合に、迅速かつ先行的に更新可能であり、 実際に更新されることを保証しなければならない MUST

完全にサンドボックス化されていない、かつ/またはプラットフォーム機能を使用する CDM 実装を悪用すると、攻撃者が OS またはプラットフォーム機能にアクセスしたり、 権限を昇格させたり(たとえば system または root として実行したり)、かつ/またはドライバー、 カーネル、ファームウェア、ハードウェアなどにアクセスしたりできる可能性がある。 そのような機能、ソフトウェア、およびハードウェアは、悪意あるソフトウェアまたは ウェブベースの攻撃に対して堅牢になるように書かれていない可能性があり、特に ユーザーエージェントと比較して、セキュリティ修正で更新されない可能性がある。 CDM 実装におけるセキュリティ 脆弱性の修正が存在しない、頻度が低い、または遅いことは、リスクを増大させる。そのような CDM 実装およびそれらを公開する UA は、すべてのデータの解析を含め、 セキュリティのあらゆる領域において特に注意しなければならない MUST

注記

ユーザーエージェントは、クライアント OS、プラットフォーム、かつ/またはハードウェアの一部である、 またはそれらによって提供される CDM または下位機構を 使用する場合、特に慎重であるべきである。

ユーザーエージェントが、十分にサンドボックス化できない、またはその他の方法で十分に 保護できない Key System 実装をサポートすることを選択する場合、 ユーザーエージェントは、それを読み込む、または呼び出す前に、ユーザーが十分に情報を得ていること、かつ/または明示的な同意を与えることを保証する べきである SHOULD

注記

認証されていないオリジンに許可を与えることは、ネットワーク攻撃者が存在する場合、 任意のオリジンにその許可を与えることと同等である。永続化された同意の濫用を参照。

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 フィンガープリンティング

悪意あるアプリケーションは、サポートされている Key Systems のリストおよび関連情報を検出または 列挙することにより、ユーザーまたはユーザーエージェントをフィンガープリントできる可能性がある。適切な オリジン保護が提供されていない場合、これには、訪問済みのサイトの検出や、 それらのサイトのために保存された情報が含まれる可能性がある。特に、Key Systems は、origins 間で鍵またはその他のデータを共有しては ならない

この仕様のいくつかの機能は、フィンガープリンティングにわずかに寄与し得る能力情報を公開する:

11.3 情報漏洩

11.3.1 懸念

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

CDM、特にユーザーエージェントの外部で実装されるものは、Webプラットフォームと同じ基本的な 分離を持たないことがある。特にオリジンをまたぐ情報漏洩を避けるために対策を講じることが 重要である。これにはメモリ内データと保存済みデータの両方が含まれる。そうしない場合、 プライベートブラウジングセッションへの/からの情報漏洩、閲覧 プロファイルをまたぐ漏洩(オペレーティングシステムのユーザーアカウント間を含む)、 さらには異なるブラウザーまたはアプリケーション間での漏洩につながる可能性がある。

11.3.2 軽減策

そのような問題を避けるため、ユーザーエージェントおよび CDM 実装は、次を保証しなければならない MUST

  • CDM は、 MediaKeys オブジェクトと 1 対 1 に 関連付けられる CDM インスタンスという概念を持つ。

  • キー、ライセンス、その他のセッションデータ、およびセッションの存在は、 セッションを作成した MediaKeys オブジェクトに関連付けられた CDM インスタンスに制限される。

  • セッションデータは、MediaKeys オブジェクト間または CDM インスタンス間で共有されない。

  • セッションデータは、そのセッションを作成した MediaKeys オブジェクトに関連付けられていない メディア要素とは共有されない。とりわけ、これは、 セッションの鍵が、その mediaKeys 属性が 当該 MediaKeys オブジェクトではない メディア要素によって読み込まれたコンテンツを復号するために使用されては ならないことを意味する。

  • MediaKeys オブジェクトおよび基盤となる 実装は、origin の外部に 情報を公開しない。

  • 永続化されたセッションデータは、該当する場合、origin ごとに保存される。

  • 要求元の origin によって保存されたデータのみを読み込むことができる。

  • この仕様で明示的に記述されていない、またはユーザーの許可なしに他のウェブプラットフォーム API を 通じてページに利用可能でない情報を、CDM から抽出、導出、または推測することはできない。 これは、たとえば CDM メッセージ内など、 クライアントデバイスの外部またはアプリケーションに公開される任意の情報に適用される。

    注記

    この要件の対象となる情報の種類には、次が含まれるが、これらに限定されない:

    • 位置情報(地理位置情報を含む)

    • Distinctive Identifiers 以外の認証情報または識別子

    • OS アカウント名およびその他の潜在的な PII

    • 類似の情報を含む可能性があるローカルディレクトリパス。

    • ローカルネットワークの詳細(たとえば、デバイスのローカル IP アドレス)

    • Bluetooth、USB、およびユーザーメディアを含むがこれらに限定されないローカルデバイス。

    • この仕様で定義される API に関連付けられていない、またはその結果として保存されていない ユーザー状態。

11.4 ユーザー追跡

11.4.1 懸念

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

第三者ホスト(または広告主など、複数のサイトにコンテンツを配信させることができる任意の エンティティ)は、Distinctive Identifier、または CDM によって、またはそれに代わって保存された、ライセンス、 キー、キー ID、またはライセンス破棄の記録を含む 永続データを使用して、複数のセッション(origin および閲覧プロファイルをまたぐものを含む)にわたって ユーザーを追跡し、ユーザーの活動または関心のプロファイルを構築することができる。 そのような追跡は、ウェブプラットフォームの残りの部分によって提供されるプライバシー保護を 損ない、たとえば、それ以外では不可能な高度にターゲット化された広告を可能にし得る。 ユーザーの実際の身元を認識しているサイト(たとえば、認証済み資格情報を必要とする コンテンツプロバイダーまたは電子商取引サイト)と組み合わせることで、純粋に匿名の ウェブ利用の世界よりも高い精度で、抑圧的な集団が個人を標的にできる可能性がある。

この仕様の API の実装を介して取得され得る、ユーザーまたはクライアント固有の情報には 次が含まれる:

この仕様は、そのような情報が一般にユーザーエージェント(および関連付けられた 閲覧 プロファイルのストレージ)の外部に、しばしば CDM 内に保存されるため、特有の懸念を示す。

ライセンスおよびライセンス破棄の記録の内容は Key System 固有であり、またキー ID は任意の値を含み得るため、 これらのデータ項目は、ユーザー識別情報を保存するために悪用される可能性がある。

Key Systems は、デバイスまたはデバイスのユーザーに対する 永続的または半永続的な識別子にアクセスしたり、それを作成したりする場合がある。 場合によっては、これらの識別子が特定のデバイスに安全な方法で結び付けられることがある。 これらの識別子が Key System メッセージ内に存在する場合、 デバイスかつ/またはユーザーが追跡される可能性がある。以下の緩和策が適用されない場合、 これには、時間の経過にわたるユーザー/デバイスの追跡と、所与のデバイスの複数ユーザーの 関連付けの両方が含まれ得る。

そのような識別子、特に消去不能、非origin固有、 または永続的な識別子は、Cookie [COOKIES] や URL に 埋め込まれたセッション識別子などの既存の技法の追跡影響を超えることに注意することが重要である。

緩和されない場合、そのような追跡は、 Key System の設計に応じて、次の 3 つの形態を取り得る:

  • すべての場合において、そのような識別子は、 Key System を完全にサポートする サイトかつ/またはサーバー(したがって Key System メッセージを解釈できるもの)に利用可能であることが予想され、そのようなサイトによる 追跡を可能にする。

  • Key Systems によって公開される識別子が origin 固有でない場合、 Key System を完全にサポートする 2 つのサイトかつ/またはサーバーが共謀してユーザーを追跡する可能性がある。

  • Key System メッセージが、たとえば特定のコンテンツ項目に対する 初期 Key System メッセージの一部が時間の経過によって変化せず、ユーザー識別子に依存するような形で、 ユーザー識別子から一貫した方法で導出された情報を含む場合、この情報は任意の アプリケーションによって、時間の経過にわたってデバイスまたはユーザーを追跡するために 使用され得る。

さらに、Key System が、キーまたはその他のデータを保存し、 origin 間で再利用することを許可する場合、2 つの origin が共謀し、共通キーにアクセスできる 能力を記録することによって、一意のユーザーを追跡できる可能性がある。

最後に、Key Systems の ユーザー制御のための任意のユーザーインターフェイスが、HTTP セッション Cookie [COOKIES] または 永続ストレージ内のデータとは別にデータを表示する場合、ユーザーはサイトの認可を変更したり、 あるデータを削除したりしても、他のものはそうしない可能性が高い。これにより、サイトは さまざまな機能を相互の冗長なバックアップとして使用できるようになり、ユーザーが自身の プライバシーを保護しようとする試みを無効にしてしまう。

サイトおよびその他の第三者がユーザーを追跡する可能性に加えて、ユーザーエージェントの 実装者、CDM ベンダー、またはデバイスベンダーは、ユーザーが訪問する、 この仕様で定義される API を使用するサイトなど、ユーザーの活動または関心のプロファイルを 構築できる可能性がある。そのような追跡は、ウェブプラットフォームの残りの部分によって 提供されるプライバシー保護、特に origin の分離に関連するものを損なう。

Distinctive Identifiers などの識別子は、CDM ベンダーによって運用または提供されるサーバーから、たとえば individualization 処理を介して取得される場合がある。この処理には、 Distinctive Permanent Identifier(s) を含むクライアント識別子をサーバーに提供することが含まれ得る。 origin ごとの識別子を生成するために、origin を表す値も提供される場合がある。

そのような実装では、CDM ベンダーは、訪問した origin の数や 新しい識別子が必要になった回数など、ユーザーの活動を追跡できる可能性がある。 origin または origin と関連付け可能な値が識別子要求に提供される場合、 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"初期化データ 形式. Xiaohan Wang; Greg Freedman. W3C. 2026年6月4日. W3C作業グループノート. URL: https://www.w3.org/TR/eme-initdata-keyids/
[EME-INITDATA-REGISTRY]
Encrypted Media Extensions 初期化データ形式レジストリー. Xiaohan Wang; Greg Freedman. W3C. 2026年7月7日 . 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]
Permissions Policy. Ian Clelland. W3C. 2026年6月18日. W3C作業草案. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFCで要件レベルを示すために用いる キーワード. S. Bradner. IETF. 1997年3月. 現在の最良慣行. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC6381]
"Bucket"メディア型のための'Codecs'および'Profiles' パラメーター. R. Gellens; D. Singer; P. Frojdh. IETF. 2011年8月. 提案標準. URL: https://www.rfc-editor.org/info/rfc6381/
[RFC7517]
JSON Web Key(JWK). M. Jones. IETF. 2015年5月. 提案標準. URL: https://www.rfc-editor.org/info/rfc7517/
[RFC8174]
RFC 2119キーワードにおける大文字と小文字の 曖昧性. B. Leiba. IETF. 2017年5月. 現在の最良慣行. URL: https://www.rfc-editor.org/info/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システム技術 — 第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]
Encrypted Media Extensions HDCP バージョンレジストリー. Xiaohan Wang; Greg Freedman. W3C. 2026年6月9日. DRY. URL: https://www.w3.org/TR/eme-hdcp-version-registry/
[EME-STREAM-REGISTRY]
Encrypted Media Extensionsストリーム形式 レジストリー. Xiaohan Wang; Greg Freedman. W3C. 2026年7月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月. 現在の最良 慣行. URL: https://www.rfc-editor.org/info/rfc6838/
[RFC7515]
JSON Web Signature(JWS). M. Jones; J. Bradley; N. Sakimura. IETF. 2015年5月. 提案標準. URL: https://www.rfc-editor.org/info/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/