Files
revkit/docs/spec/01_chrome.md
T
tkgstratorandClaude Opus 4.6 d91af8380b docs: Netflix仕様書の再構成とiOS解析ドキュメント追加
- 旧ドキュメント (docs/netflix/, docs/instructions/ 等) を削除
- docs/spec/: appboot ピンニング解析、iOS再生フロー、
  MSL CBOR鍵交換解析、キャプチャ復号状況、暗号化フロー図を追加
- docs/netflix_client_spec.md, platform_flow_comparison.md を追加
- iOS認証・マニフェスト・ライセンス取得フロー詳細を追加

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 02:06:14 +00:00

3.9 KiB

Netflix MSL クライアント仕様: Chrome

共通仕様: 00_common.md


1. フロー

%%{init: {'theme': 'dark'}}%%
sequenceDiagram
    participant Browser as Chrome (XHR)
    participant MSL as MSL Gateway<br/>(www.netflix.com)
    participant CDM as Widevine CDM (EME)

    rect rgba(80, 80, 80, 0.3)
    Note over Browser,MSL: 認証・鍵交換
    Browser->>MSL: /aleProvision (pbo_tokens/router)
    Note right of Browser: ASYMMETRIC_WRAPPED(JWK_RSA)<br/>Cookie: NetflixId, SecureNetflixId
    MSL-->>Browser: ALE 鍵 (HMAC + AES)
    end

    rect rgba(60, 100, 60, 0.3)
    Note over Browser,CDM: マニフェスト → ライセンス → 復号
    Browser->>MSL: /pbo_manifests/router (MSL暗号化)
    MSL-->>Browser: マニフェスト (AV1 streams, KID)
    Browser->>CDM: generateRequest (PSSH initData)
    CDM-->>Browser: license-request (protobuf, ~3992 bytes)
    Browser->>MSL: /pbo_licenses/router
    MSL-->>Browser: license-response (content keys)
    Browser->>CDM: update (license-response)
    CDM-->>Browser: keystatuseschange (usable)
    Note over Browser: MSE + EME で DASH セグメント復号・再生
    end

    rect rgba(80, 80, 80, 0.3)
    Note over Browser,MSL: テレメトリ
    loop 再生中
        Browser->>MSL: /events (position, trackId)
    end
    end

2. 認証

項目 値
ESN プレフィックス NFCDCH-MC-
ESN 例 NFCDCH-MC-MW4H1YWDGE9911H107X9CTG5CK58MH
ESN 取得方法 事前割り当て済み (Netflix JS から取得)
認証スキーム NETFLIXID (Cookie + UIT)
鍵交換方式 ASYMMETRIC_WRAPPED (JWK_RSA)
MSL 圧縮 LZW
NetflixId=ct%3DBgjHlOvcAx...
SecureNetflixId=v%3D3%26mac%3DAQEAEQAB...
nfvdid=BQFmAAEBEAQQ...

MSL Envelope 固有フィールド

{
  "sender": "NFCDCH-MC-...",
  "keyrequestdata": [{ "scheme": "ASYMMETRIC_WRAPPED", "keydata": { "keypairid": "...", "mechanism": "JWK_RSA" } }],
  "userauthdata": { "scheme": "NETFLIXID" },
  "useridtoken": { "tokendata": "...", "signature": "..." },
  "servicetokens": [{ "name": "cad" }, { "name": "sf" }],
  "capabilities": { "compressionalgos": ["LZW"] },
  "handshake": false,
  "renewable": true
}

3. マニフェスト取得

エンドポイント: POST /nq/msl_v1/cadmium/pbo_manifests/^1.0.0/router

MSL 暗号化。レスポンスは LZW 圧縮。

提供されるコーデック (実測): AV1 のみ

解像度 ビットレート プロファイル
480x270 83 kbps av1-main-L30-dash-cbcs-prk
1920x1080 1412 kbps av1-main-L40-dash-cbcs-prk

4. ライセンスチャレンジ

エンドポイント: POST /nq/msl_v1/cadmium/pbo_licenses/^1.0.0/router

EME フロー

// 1. PSSH から initData
const psshBytes = base64Decode(manifest.result.video_tracks[0].drmHeader.bytes);

// 2. EME session
const keySystem = "com.widevine.alpha";
const session = mediaKeys.createSession();
session.generateRequest("cenc", psshBytes);

// 3. session.onmessage → license-request protobuf を MSL 経由で送信
// 4. レスポンスを session.update() に渡す

実測値

項目 値
keySystem com.widevine.alpha
Session ID 例 5F926325C6E5A1FECB33604130D585D5
license-request サイズ ~3992 bytes
license-response サイズ ~1030 bytes
messageType license-request, license-renewal

5. HTTP ヘッダー

Content-Encoding: msl_v1
Content-Type: text/plain
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36
Cookie: NetflixId=...; SecureNetflixId=...; nfvdid=...

URL クエリパラメータ (全 MSL リクエスト共通):

clienttype=akira
uiversion=v930f5871
browsername=chrome
browserversion=146.0.0.0
osname=windows
osversion=10.0