Question/Feature request - Custom DRM using Wasm
venomone opened this issue · 1 comments
Dear VideoJS Team, and all the other folks developing on the VHS/VideoJS base,
I would like to be able to manipulate the Key exchange process of my AES-128 encrypted content, sadly I can't do this at the moment of writing as there are no hooks present I could potentially access at the VideoJS stack. My Idea is that I can at least similar as for the EME plugin trigger a function like the getLicense call but for AES-128 protected content. I'm aware that this does not provide the same level of security as a commercial DRM system, but it's a thousand times cheaper and from my understanding and testing the key exchange process can be heavily obfuscated by using WebAssembly.
The Idea basically is that VideoJS fetches the following line in my m3u8 manifest a bit differently.
Normally, the line would look something like this (Method 1):
#EXT-X-KEY:METHOD=AES-128,URI="https://example.com/license/8cefe6f8-ebf8-4e88-8440-920be62099e9/-6QgbtD5yTu6kz20kFnemCGc9_SqC6_I0UgcTRGpUqFewmUZkcFyo8TQ-rVN9XwP",IV=ac4cfa42cfb18213873b3a857791d6b0
But what If we would make this instead (Method 2):
#EXT-X-KEY:METHOD=AES-128,KEYID="8cefe6f8-ebf8-4e88-8440-920be62099e9",IV=ac4cfa42cfb18213873b3a857791d6b0
If I was able to make VideoJS return the Keyid of the EXT-X-KEY line, I could pass the KeyId along with a JWT to my Wasm module. The Wasm module will securely handle the key exchange in memory and returns a ClearKey JSON object like this one:
{"keys":[{"alg":"A128KW","k":"NDE4OTA3ZTBmNTE0NDk5ZWJjMjRlMWJiMmMwOTAyNjE","kid":"NjViM2VlOWItYTk2Yi00NDBlLTk3YjEtY2JkZjhiMWVhN2Ex","kty":"oct"}],"type":"temporary"}
Then somehow this ClearKey license needs to get saved to the browsers' EME storage. I'm not a 100% sure about the CDM in that case, but maybe you folks could provide some more details onto this, maybe the VHS decryption worker is already enough here?!
Is such a solution possible? If yes, please get back to me, maybe we can work something out, I have a fully working server client implementation already setup.
Besides, I would also like to mention the following, when using methode1, the URI and the reference to the key, espcially the domain, is hardcoded into the playlist, which is generally speaking not a good idea, If you maybe change the name of your domain, it will get a bit dirty to fix this up, espcially if you have a lot of streams...
Currently, the only way to Hotfix this would be something like this:
videojs.Vhs.xhr.beforeRequest = (options: any) => {
// Set the Authorization header
options.headers = { Authorization: this.file_response.access_token };
// Enable withCredentials
options.withCredentials = true;
if (options.uri && options.uri.includes('olddomain.com')) {
// Replace the old domain with the actual new domain we now fetch the decryption key from
options.uri = options.uri.replace('olddomain.com', newdomain.com');
}
return options;
};
Thanks in advance
Is there really nobody that can give me an Idea on how to implement this with VideoJS side?