mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
87 lines
2.3 KiB
JavaScript
87 lines
2.3 KiB
JavaScript
![]() |
/*
|
||
|
* AES128 decryption.
|
||
|
*/
|
||
|
|
||
|
import AES128Decrypter from './aes128-decrypter';
|
||
|
import {ErrorTypes, ErrorDetails} from '../errors';
|
||
|
import {logger} from '../utils/logger';
|
||
|
|
||
|
class Decrypter {
|
||
|
|
||
|
constructor(hls) {
|
||
|
this.hls = hls;
|
||
|
try {
|
||
|
const browserCrypto = window ? window.crypto : crypto;
|
||
|
this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;
|
||
|
this.disableWebCrypto = !this.subtle;
|
||
|
} catch (e) {
|
||
|
this.disableWebCrypto = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
destroy() {
|
||
|
}
|
||
|
|
||
|
decrypt(data, key, iv, callback) {
|
||
|
if (this.disableWebCrypto && this.hls.config.enableSoftwareAES) {
|
||
|
this.decryptBySoftware(data, key, iv, callback);
|
||
|
} else {
|
||
|
this.decryptByWebCrypto(data, key, iv, callback);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
decryptByWebCrypto(data, key, iv, callback) {
|
||
|
logger.log('decrypting by WebCrypto API');
|
||
|
|
||
|
this.subtle.importKey('raw', key, { name : 'AES-CBC', length : 128 }, false, ['decrypt']).
|
||
|
then((importedKey) => {
|
||
|
this.subtle.decrypt({ name : 'AES-CBC', iv : iv.buffer }, importedKey, data).
|
||
|
then(callback).
|
||
|
catch ((err) => {
|
||
|
this.onWebCryptoError(err, data, key, iv, callback);
|
||
|
});
|
||
|
}).
|
||
|
catch ((err) => {
|
||
|
this.onWebCryptoError(err, data, key, iv, callback);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
decryptBySoftware(data, key8, iv8, callback) {
|
||
|
logger.log('decrypting by JavaScript Implementation');
|
||
|
|
||
|
var view = new DataView(key8.buffer);
|
||
|
var key = new Uint32Array([
|
||
|
view.getUint32(0),
|
||
|
view.getUint32(4),
|
||
|
view.getUint32(8),
|
||
|
view.getUint32(12)
|
||
|
]);
|
||
|
|
||
|
view = new DataView(iv8.buffer);
|
||
|
var iv = new Uint32Array([
|
||
|
view.getUint32(0),
|
||
|
view.getUint32(4),
|
||
|
view.getUint32(8),
|
||
|
view.getUint32(12)
|
||
|
]);
|
||
|
|
||
|
var decrypter = new AES128Decrypter(key, iv);
|
||
|
callback(decrypter.decrypt(data).buffer);
|
||
|
}
|
||
|
|
||
|
onWebCryptoError(err, data, key, iv, callback) {
|
||
|
if (this.hls.config.enableSoftwareAES) {
|
||
|
logger.log('disabling to use WebCrypto API');
|
||
|
this.disableWebCrypto = true;
|
||
|
this.decryptBySoftware(data, key, iv, callback);
|
||
|
}
|
||
|
else {
|
||
|
logger.error(`decrypting error : ${err.message}`);
|
||
|
this.hls.trigger(Event.ERROR, {type : ErrorTypes.MEDIA_ERROR, details : ErrorDetails.FRAG_DECRYPT_ERROR, fatal : true, reason : err.message});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export default Decrypter;
|