feat: implement decrypt from user key
This commit is contained in:
parent
dd63aa4765
commit
ba503ff46f
@ -21,7 +21,7 @@
|
|||||||
"@chakra-ui/react": "^2.7.0",
|
"@chakra-ui/react": "^2.7.0",
|
||||||
"@emotion/react": "^11.11.0",
|
"@emotion/react": "^11.11.0",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@jixun/libparakeet": "0.1.1",
|
"@jixun/libparakeet": "0.1.2",
|
||||||
"@reduxjs/toolkit": "^1.9.5",
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
"framer-motion": "^10.12.16",
|
"framer-motion": "^10.12.16",
|
||||||
"immer": "^10.0.2",
|
"immer": "^10.0.2",
|
||||||
|
@ -21,8 +21,8 @@ dependencies:
|
|||||||
specifier: ^11.11.0
|
specifier: ^11.11.0
|
||||||
version: 11.11.0(@emotion/react@11.11.0)(@types/react@18.2.7)(react@18.2.0)
|
version: 11.11.0(@emotion/react@11.11.0)(@types/react@18.2.7)(react@18.2.0)
|
||||||
'@jixun/libparakeet':
|
'@jixun/libparakeet':
|
||||||
specifier: 0.1.1
|
specifier: 0.1.2
|
||||||
version: 0.1.1
|
version: 0.1.2
|
||||||
'@reduxjs/toolkit':
|
'@reduxjs/toolkit':
|
||||||
specifier: ^1.9.5
|
specifier: ^1.9.5
|
||||||
version: 1.9.5(react-redux@8.0.5)(react@18.2.0)
|
version: 1.9.5(react-redux@8.0.5)(react@18.2.0)
|
||||||
@ -3101,8 +3101,8 @@ packages:
|
|||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@jixun/libparakeet@0.1.1:
|
/@jixun/libparakeet@0.1.2:
|
||||||
resolution: {integrity: sha512-1e6hFsVga3eDkQvUY/wsX/F1R94SzcrO2u7wK/KPaCs9MD0hej+cgraOixp+VDy4uqGSPKU5iNP1a8hCYze2rg==}
|
resolution: {integrity: sha512-PxhA7EtC3ss3ACxaGckgD41wGAhWllfy80LfL8GMiXkdXMipgcfFfeEcJBBpvTZ/FlDfoFLDJSOz0uculhsgnQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@jridgewell/gen-mapping@0.3.3:
|
/@jridgewell/gen-mapping@0.3.3:
|
||||||
@ -4069,8 +4069,8 @@ packages:
|
|||||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001497
|
caniuse-lite: 1.0.30001498
|
||||||
electron-to-chromium: 1.4.426
|
electron-to-chromium: 1.4.427
|
||||||
node-releases: 2.0.12
|
node-releases: 2.0.12
|
||||||
update-browserslist-db: 1.0.11(browserslist@4.21.7)
|
update-browserslist-db: 1.0.11(browserslist@4.21.7)
|
||||||
dev: true
|
dev: true
|
||||||
@ -4123,8 +4123,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==}
|
resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/caniuse-lite@1.0.30001497:
|
/caniuse-lite@1.0.30001498:
|
||||||
resolution: {integrity: sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==}
|
resolution: {integrity: sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/chai@4.3.7:
|
/chai@4.3.7:
|
||||||
@ -4478,8 +4478,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-5VXLW4Qw89vM2WTICHua/y8v7fKGDRVa2VPOtBB9IpLvW316B+xd8yD1wTmLPY2ot/00P/qt87xdolj4aG/Lzg==}
|
resolution: {integrity: sha512-5VXLW4Qw89vM2WTICHua/y8v7fKGDRVa2VPOtBB9IpLvW316B+xd8yD1wTmLPY2ot/00P/qt87xdolj4aG/Lzg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/electron-to-chromium@1.4.426:
|
/electron-to-chromium@1.4.427:
|
||||||
resolution: {integrity: sha512-dWuNH+XUT9hdFHASfMpcZGW5kUyJvllumJkXaXiswuCkoaFIFI89aykBPuHEi1YUWQGRCqvIO0BUdmeFJ4W4Ww==}
|
resolution: {integrity: sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/emoji-regex@8.0.0:
|
/emoji-regex@8.0.0:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CryptoFactory } from './CryptoBase';
|
import { CryptoFactory } from './CryptoBase';
|
||||||
|
|
||||||
import { QMC1Crypto } from './qmc/qmc_v1';
|
import { QMC1Crypto } from './qmc/qmc_v1';
|
||||||
import { QMC2Crypto } from './qmc/qmc_v2';
|
import { QMC2Crypto, QMC2CryptoWithKey } from './qmc/qmc_v2';
|
||||||
import { XiamiCrypto } from './xiami/xiami';
|
import { XiamiCrypto } from './xiami/xiami';
|
||||||
import { KGMCrypto } from './kgm/kgm_pc';
|
import { KGMCrypto } from './kgm/kgm_pc';
|
||||||
import { NCMCrypto } from './ncm/ncm_pc';
|
import { NCMCrypto } from './ncm/ncm_pc';
|
||||||
@ -14,6 +14,7 @@ export const allCryptoFactories: CryptoFactory[] = [
|
|||||||
XiamiCrypto.make,
|
XiamiCrypto.make,
|
||||||
|
|
||||||
// QMCv2 (*.mflac)
|
// QMCv2 (*.mflac)
|
||||||
|
QMC2CryptoWithKey.make,
|
||||||
QMC2Crypto.make,
|
QMC2Crypto.make,
|
||||||
|
|
||||||
// NCM (*.ncm)
|
// NCM (*.ncm)
|
||||||
|
@ -1,16 +1,49 @@
|
|||||||
import { transformBlob } from '~/decrypt-worker/util/transformBlob';
|
import { transformBlob } from '~/decrypt-worker/util/transformBlob';
|
||||||
import type { CryptoBase } from '../CryptoBase';
|
import type { CryptoBase } from '../CryptoBase';
|
||||||
|
import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts';
|
||||||
import { SEED, ENC_V2_KEY_1, ENC_V2_KEY_2 } from './qmc_v2.key.ts';
|
import { SEED, ENC_V2_KEY_1, ENC_V2_KEY_2 } from './qmc_v2.key.ts';
|
||||||
|
import { fetchParakeet } from '@jixun/libparakeet';
|
||||||
|
|
||||||
export class QMC2Crypto implements CryptoBase {
|
export class QMC2Crypto implements CryptoBase {
|
||||||
cryptoName = 'QMC/v2';
|
cryptoName = 'QMC/v2';
|
||||||
checkByDecryptHeader = false;
|
checkByDecryptHeader = false;
|
||||||
|
|
||||||
async decrypt(buffer: ArrayBuffer): Promise<Blob> {
|
async decrypt(buffer: ArrayBuffer): Promise<Blob> {
|
||||||
return transformBlob(buffer, (p) => p.make.QMCv2(p.make.QMCv2FooterParser(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2)));
|
// FIXME: Move the cleanup to transformBlob
|
||||||
|
const mod = await fetchParakeet();
|
||||||
|
const footerParser = mod.make.QMCv2FooterParser(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2);
|
||||||
|
return transformBlob(buffer, (p) => p.make.QMCv2(footerParser)).finally(() => {
|
||||||
|
footerParser.delete();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static make() {
|
public static make() {
|
||||||
return new QMC2Crypto();
|
return new QMC2Crypto();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class QMC2CryptoWithKey implements CryptoBase {
|
||||||
|
cryptoName = 'QMC/v2 (key)';
|
||||||
|
checkByDecryptHeader = true;
|
||||||
|
|
||||||
|
async checkBySignature(_buffer: ArrayBuffer, options: DecryptCommandOptions): Promise<boolean> {
|
||||||
|
return Boolean(options.qmc2Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
async decrypt(buffer: ArrayBuffer, options: DecryptCommandOptions): Promise<Blob> {
|
||||||
|
if (!options.qmc2Key) {
|
||||||
|
throw new Error('key was not provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Move the cleanup to transformBlob
|
||||||
|
const mod = await fetchParakeet();
|
||||||
|
const textEncoder = new TextEncoder();
|
||||||
|
const key = textEncoder.encode(options.qmc2Key);
|
||||||
|
const keyCrypto = mod.make.QMCv2KeyCrypto(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2);
|
||||||
|
return transformBlob(buffer, (p) => p.make.QMCv2EKey(key, keyCrypto));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static make() {
|
||||||
|
return new QMC2CryptoWithKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user