Files
revkit/docs/instructions/pxa_esn_llm.md
T

3.9 KiB

PXA ESN — LLM 向けリファレンス

PXA ESN とは

Netflix Android アプリがサーバーから取得するデバイス識別子。ローカル生成の Base ESN (PRV) に対し、サーバーが fingerprint を付与して発行する。API リクエストの X-Netflix.esn ヘッダーで使用される。

取得プロトコル

  • 経路: MSL (Message Security Layer) over HTTPS
  • エンドポイント: /getProxyEsn
  • 取得方法: Cookie ではなく、MSL レスポンスの JSON ボディで返される

リクエスト

{"url": "/getProxyEsn"}

MSL VolleyRequest のヘッダーに router: getProxyEsn が設定される。HTTP レベルのヘッダーは MSL 暗号化されるため外部からは見えない。

レスポンス

{
  "id": 1,
  "version": 2,
  "serverTime": 1773478742949,
  "result": {
    "esn": "NFANDROID1-PXA-P-L3-GOOGLPIXEL=4A==5G=-22594-02028KVLM5OU1MSB..."
  },
  "common": {},
  "from": "playapi"
}

PXA ESN は result.esn に格納されている。

有効期限

  • 設定値: EsnHendrixConfig.refreshProxyEsnTimeInMs = 0
  • TTL が 0 のため 無期限キャッシュ
  • 一度取得したら SharedPreferences に永続化され、以下の場合のみ再取得:
    • 初回インストール
    • アプリデータクリア
    • SharedPreferences の消失
    • masterTokenSerialNumber の変更

fingerprint の特性

  • サーバー側で生成され、ローカルでは再現不可
  • 同一デバイスでも取得ごとに異なる fingerprint が返される
  • 実測で 3 回取得し、毎回異なることを確認

ESN 構造

NFANDROID1-PXA-P-L3-GOOGLPIXEL=4A==5G=-22594-0202{fingerprint}
セグメント 値 説明
Platform NFANDROID1- Android プレフィックス
Type PXA Proxy (サーバー発行)
Category P Phone (T=Tablet, B=TV, C=ChromeOS, E=Display)
Security L3 Widevine Security Level
Model GOOGLPIXEL=4A==5G= サニタイズ済みデバイスモデル
systemId 22594 Widevine systemId
fingerprint 0202... サーバー発行 (毎回異なる)

保存先

SharedPreferences に 2 つのキーで保存:

キー 型 内容
nf_drm_esn String PXA ESN 文字列
nf_drm_proxy_esn String (JSON) {"esn":"...","ts":epoch_ms,"sn":serial_number}

使用箇所

ヘッダー 使用先
X-Netflix.esn GraphQL / Cronet リクエスト
X-Netflix-ProxyEsn WebSocket / MSL リクエスト

コードパス

WidevineEntityAuthEsnProviderImpl.c(serialNumber)  -- 再取得が必要か判定
  → ProxyEsnMslRequest                             -- MSL リクエスト送信
    → body: {"url": "/getProxyEsn"}
    → Netflix playapi サーバー
  ← onSuccess(JSONObject)                           -- レスポンス受信
    → result.esn を抽出
  → ProxyEsn.onKnown(serialNumber, esn)            -- SharedPreferences に保存

関連クラス

クラス ファイルパス 役割
ProxyEsnMslRequest mslagent/impl/ProxyEsnMslRequest.java MSL リクエスト発行・レスポンス処理
ProxyEsn esn/impl/ProxyEsn.java キャッシュ管理・永続化
WidevineEntityAuthEsnProviderImpl esn/impl/WidevineEntityAuthEsnProviderImpl.java ESN 統合管理
EsnHendrixConfig (o.fkQ) o/C13212fkQ.java TTL 設定 (refreshProxyEsnTimeInMs)

キャプチャ方法

hook_msl.js を使用。ProxyEsn.$init で expired フラグを強制 true にすることで、キャッシュの有無に関係なく getProxyEsn を発火させられる。

./run_android.sh hook_msl.js

出力イベント: proxyEsn.forceExpired, proxyEsn.request, proxyEsn.requestHeaders, proxyEsn.response, proxyEsn.onKnown, proxyEsn.error