An extension-based proxy for Widevine/ClearKey EME challenges and license messages. Modifies the challenge before it reaches the web player. Bypasses Hashes, one-time-tokens and license wrapping.
JavaScript
1,147
40 commits
updated Sep 6, 2026
An extension-based proxy for Widevine/ClearKey EME challenges and license messages.
Modifies the challenge before it reaches the web player and retrieves the decryption keys from the response.
This addon requires a Widevine device to work, either locally or remotely:
chrome://extensions/Developer modeabout:addonsInstall Add-on From File...about:debugging#/runtime/this-firefoxLoad Temporary Add-on... and select the downloaded fileSelect your device type in the popup window and follow the steps for either type below
If you only have a device_client_id_blob and device_private_key, run this command to create a .wvd file:
pywidevine create-device -k device_private_key -c device_client_id_blob -t "ANDROID" -l 3
Open the dropdown and click + Choose File, in the window that opens, click Choose File again and select the created .wvd file.
Open the dropdown and click + Choose File, in the window that opens, click Choose File again and select the supplied remote.json file.
Once you've at least installed one Widevine device, play a video on a page that you think uses Widevine DRM and the keys should in the Keys section.
This section only shows the most recent keys (past 5 min.), to see all keys, click History on the right to open the history page.
| Name | Activated by |
|---|---|
MediaKeys | MediaKeySystemAccess.createMediaKeys() called |
Session | MediaKeys.createSession() called |
Generated | MediaKeySession.generateRequest() called |
Challenge | MediaKeyMessageEvent occurred with .message.byteLength > 2 |
License | MediaKeySession.update() called with SignedMessage of type LICENSE |
The table below does not cover 100% of cases but is accurate enough.
| Keys appear | Video plays | DRM status | Possible cause | Possible fix |
|---|---|---|---|---|
| No | Yes | Challenge / License | The page does not use DRM | |
| No | Yes | Challenge / License | Unable to intercept messages | Try using proxy mode property, otherwise open an issue |
| No | No | Challenge / License | Unknown, likely unrelated to addon | |
| No | No | Challenge / License | Endpoint does not accept Android CDMs | (see below) |
If the license endpoint has been configured to only accept Android CDMs, you need to either:
If you just want to run this addon locally with changes applied, run npm run bundle.
Now select the src directory (or a file there within) to install the addon temporarily.
Create the following .env file with Mozilla addon dev credentials in the root directory:
API_KEY=...
API_SECRET=...
To package the previously created bundles into a single .zip/.xpi file, run npm run package. To target only a specific browser, specify the type like this: npm run package -- <chrome/firefox/both>. Supplying no arguments targets both.
This requires the bundles to be present, so it must not be run on its own.
Running npm run publish will execute both bundle and package.
400 followers · starred Sep 2026
122 followers · starred Apr 2026
243 followers · starred Dec 2025
15 followers · starred Feb 2025
An extension-based proxy for Widevine/ClearKey EME challenges and license messages. Modifies the challenge before it reaches the web player. Bypasses Hashes, one-time-tokens and license wrapping.
JavaScript
1,147
40 commits
updated Sep 6, 2026
An extension-based proxy for Widevine/ClearKey EME challenges and license messages.
Modifies the challenge before it reaches the web player and retrieves the decryption keys from the response.
This addon requires a Widevine device to work, either locally or remotely:
chrome://extensions/Developer modeabout:addonsInstall Add-on From File...about:debugging#/runtime/this-firefoxLoad Temporary Add-on... and select the downloaded fileSelect your device type in the popup window and follow the steps for either type below
If you only have a device_client_id_blob and device_private_key, run this command to create a .wvd file:
pywidevine create-device -k device_private_key -c device_client_id_blob -t "ANDROID" -l 3
Open the dropdown and click + Choose File, in the window that opens, click Choose File again and select the created .wvd file.
Open the dropdown and click + Choose File, in the window that opens, click Choose File again and select the supplied remote.json file.
Once you've at least installed one Widevine device, play a video on a page that you think uses Widevine DRM and the keys should in the Keys section.
This section only shows the most recent keys (past 5 min.), to see all keys, click History on the right to open the history page.
| Name | Activated by |
|---|---|
MediaKeys | MediaKeySystemAccess.createMediaKeys() called |
Session | MediaKeys.createSession() called |
Generated | MediaKeySession.generateRequest() called |
Challenge | MediaKeyMessageEvent occurred with .message.byteLength > 2 |
License | MediaKeySession.update() called with SignedMessage of type LICENSE |
The table below does not cover 100% of cases but is accurate enough.
| Keys appear | Video plays | DRM status | Possible cause | Possible fix |
|---|---|---|---|---|
| No | Yes | Challenge / License | The page does not use DRM | |
| No | Yes | Challenge / License | Unable to intercept messages | Try using proxy mode property, otherwise open an issue |
| No | No | Challenge / License | Unknown, likely unrelated to addon | |
| No | No | Challenge / License | Endpoint does not accept Android CDMs | (see below) |
If the license endpoint has been configured to only accept Android CDMs, you need to either:
If you just want to run this addon locally with changes applied, run npm run bundle.
Now select the src directory (or a file there within) to install the addon temporarily.
Create the following .env file with Mozilla addon dev credentials in the root directory:
API_KEY=...
API_SECRET=...
To package the previously created bundles into a single .zip/.xpi file, run npm run package. To target only a specific browser, specify the type like this: npm run package -- <chrome/firefox/both>. Supplying no arguments targets both.
This requires the bundles to be present, so it must not be run on its own.
Running npm run publish will execute both bundle and package.
400 followers · starred Sep 2026
122 followers · starred Apr 2026
243 followers · starred Dec 2025
15 followers · starred Feb 2025