From 7fef8da083f85fa8a21d8ce2e9275dc2c8567b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Mon, 16 Sep 2024 22:13:27 +0100 Subject: [PATCH] feat: add kgm support --- package.json | 2 +- pnpm-lock.yaml | 10 +++---- src/decrypt-worker/Deciphers.ts | 3 +- src/decrypt-worker/decipher/KugouMusic.ts | 36 +++++++++++++++++++++++ src/decrypt-worker/decipher/KuwoMusic.ts | 6 ++-- 5 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 src/decrypt-worker/decipher/KugouMusic.ts diff --git a/package.json b/package.json index b5afac9..eee81c2 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@emotion/styled": "^11.11.0", "@reduxjs/toolkit": "^2.0.1", "@um/libparakeet": "0.4.5", - "@unlock-music/crypto": "0.0.0-alpha.11", + "@unlock-music/crypto": "0.0.0-alpha.12", "framer-motion": "^10.16.16", "nanoid": "^5.0.4", "radash": "^11.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 492ae43..c88e5ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: 0.4.5 version: 0.4.5 '@unlock-music/crypto': - specifier: 0.0.0-alpha.11 - version: 0.0.0-alpha.11 + specifier: 0.0.0-alpha.12 + version: 0.0.0-alpha.12 framer-motion: specifier: ^10.16.16 version: 10.16.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -1927,8 +1927,8 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@unlock-music/crypto@0.0.0-alpha.11': - resolution: {integrity: sha512-lA3xryziHULhkPbuQFI2HrfwDREUD9YoaZOTMQqcu/8mKF2/hA3sCK0Uoq0miYr+7VUbE5sMBvl9dcrnCI1UWA==, tarball: https://git.unlock-music.dev/api/packages/um/npm/%40unlock-music%2Fcrypto/-/0.0.0-alpha.11/crypto-0.0.0-alpha.11.tgz} + '@unlock-music/crypto@0.0.0-alpha.12': + resolution: {integrity: sha512-Q24cq653CmD8sj/D1M6wHYtXJIX3YIgnvbPtO+aHnY07J0ZXvkqNh+6a3hBrGGLYzcSWioAw2xxf2rFEQ3q35A==, tarball: https://git.unlock-music.dev/api/packages/um/npm/%40unlock-music%2Fcrypto/-/0.0.0-alpha.12/crypto-0.0.0-alpha.12.tgz} '@vitejs/plugin-react@4.2.1': resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} @@ -6118,7 +6118,7 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@unlock-music/crypto@0.0.0-alpha.11': {} + '@unlock-music/crypto@0.0.0-alpha.12': {} '@vitejs/plugin-react@4.2.1(vite@5.0.10(@types/node@20.10.5)(sass@1.69.5)(terser@5.27.0))': dependencies: diff --git a/src/decrypt-worker/Deciphers.ts b/src/decrypt-worker/Deciphers.ts index d4782ec..ace5f1c 100644 --- a/src/decrypt-worker/Deciphers.ts +++ b/src/decrypt-worker/Deciphers.ts @@ -3,6 +3,7 @@ import { TransparentDecipher } from './decipher/Transparent.ts'; import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts'; import { QQMusicV1Decipher, QQMusicV2Decipher } from '~/decrypt-worker/decipher/QQMusic.ts'; import { KuwoMusicDecipher } from '~/decrypt-worker/decipher/KuwoMusic.ts'; +import { KugouMusicDecipher } from '~/decrypt-worker/decipher/KugouMusic.ts'; export enum Status { OK = 0, @@ -40,7 +41,7 @@ export const allCryptoFactories: DecipherFactory[] = [ NetEaseCloudMusicDecipher.make, // KGM (*.kgm, *.vpr) - // KGMCrypto.make, + KugouMusicDecipher.make, // KWMv1 (*.kwm) KuwoMusicDecipher.make, diff --git a/src/decrypt-worker/decipher/KugouMusic.ts b/src/decrypt-worker/decipher/KugouMusic.ts new file mode 100644 index 0000000..1f1fc3f --- /dev/null +++ b/src/decrypt-worker/decipher/KugouMusic.ts @@ -0,0 +1,36 @@ +import { DecipherInstance, DecipherOK, DecipherResult, Status } from '~/decrypt-worker/Deciphers'; +import { KuGouDecipher, KuGouHeader } from '@unlock-music/crypto'; +import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts'; +import { chunkBuffer } from '~/decrypt-worker/util/buffer.ts'; + +export class KugouMusicDecipher implements DecipherInstance { + cipherName = 'Kugou'; + + async decrypt(buffer: Uint8Array, _options: DecryptCommandOptions): Promise { + let kgm: KuGouDecipher | undefined; + let header: KuGouHeader | undefined; + + try { + header = KuGouHeader.parse(buffer.subarray(0, 0x400)); + kgm = new KuGouDecipher(header); + + const audioBuffer = new Uint8Array(buffer.subarray(0x400)); + for (const [block, offset] of chunkBuffer(audioBuffer)) { + kgm.decrypt(block, offset); + } + + return { + status: Status.OK, + cipherName: this.cipherName, + data: audioBuffer, + }; + } finally { + kgm?.free(); + header?.free(); + } + } + + public static make() { + return new KugouMusicDecipher(); + } +} diff --git a/src/decrypt-worker/decipher/KuwoMusic.ts b/src/decrypt-worker/decipher/KuwoMusic.ts index 8520b30..b3e7369 100644 --- a/src/decrypt-worker/decipher/KuwoMusic.ts +++ b/src/decrypt-worker/decipher/KuwoMusic.ts @@ -1,5 +1,5 @@ import { DecipherInstance, DecipherOK, DecipherResult, Status } from '~/decrypt-worker/Deciphers'; -import { KuwoHeader, KWMCipher } from '@unlock-music/crypto'; +import { KuwoHeader, KWMDecipher } from '@unlock-music/crypto'; import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts'; import { chunkBuffer } from '~/decrypt-worker/util/buffer.ts'; @@ -8,11 +8,11 @@ export class KuwoMusicDecipher implements DecipherInstance { async decrypt(buffer: Uint8Array, options: DecryptCommandOptions): Promise { let header: KuwoHeader | undefined; - let kwm: KWMCipher | undefined; + let kwm: KWMDecipher | undefined; try { header = KuwoHeader.parse(buffer.subarray(0, 0x400)); - kwm = header.makeCipher(options.kwm2key); + kwm = new KWMDecipher(header, options.kwm2key); const audioBuffer = new Uint8Array(buffer.subarray(0x400)); for (const [block, offset] of chunkBuffer(audioBuffer)) {