mirror of
https://git.fuwafuwa.moe/SMLoadrDev/SMLoadr
synced 2024-11-17 00:24:33 +01:00
Move crypto to a Service
This commit is contained in:
commit
851d7a42ab
70
SMLoadr.js
70
SMLoadr.js
@ -20,7 +20,6 @@ require('./node_modules/cache-manager/lib/stores/memory');
|
||||
const requestPlus = require('request-plus');
|
||||
const id3Writer = require('./libs/browser-id3-writer');
|
||||
const flacMetadata = require('./libs/flac-metadata');
|
||||
const crypto = require('crypto');
|
||||
const inquirer = require('inquirer');
|
||||
const fs = require('fs');
|
||||
const stream = require('stream');
|
||||
@ -37,6 +36,9 @@ const configFile = 'SMLoadrConfig.json';
|
||||
const ConfigService = require('./src/service/ConfigService');
|
||||
let configService = new ConfigService(configFile);
|
||||
|
||||
const EncryptionService = require('./src/service/EncryptionService');
|
||||
let encryptionService = new EncryptionService();
|
||||
|
||||
const Log = require('log');
|
||||
|
||||
let DOWNLOAD_DIR = 'DOWNLOADS/';
|
||||
@ -1973,15 +1975,9 @@ function sanitizeFilename(fileName) {
|
||||
* @returns {String}
|
||||
*/
|
||||
function getTrackDownloadUrl(trackInfos, trackQuality) {
|
||||
const step1 = [trackInfos.MD5_ORIGIN, trackQuality, trackInfos.SNG_ID, trackInfos.MEDIA_VERSION].join('¤');
|
||||
|
||||
let step2 = crypto.createHash('md5').update(step1, 'ascii').digest('hex') + '¤' + step1 + '¤';
|
||||
while (step2.length % 16 > 0) step2 += ' ';
|
||||
|
||||
const step3 = crypto.createCipheriv('aes-128-ecb', 'jo6aey6haid2Teih', '').update(step2, 'ascii', 'hex');
|
||||
const cdn = trackInfos.MD5_ORIGIN[0];
|
||||
|
||||
return 'https://e-cdns-proxy-' + cdn + '.dzcdn.net/mobile/1/' + step3;
|
||||
return 'https://e-cdns-proxy-' + cdn + '.dzcdn.net/mobile/1/' + encryptionService.getSongFileName(trackInfos, trackQuality);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2072,62 +2068,6 @@ function getValidTrackQuality(trackInfos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the blowfish key to decrypt the track
|
||||
*
|
||||
* @param {Object} trackInfos
|
||||
*/
|
||||
function getBlowfishKey(trackInfos) {
|
||||
const SECRET = 'g4el58wc0zvf9na1';
|
||||
|
||||
const idMd5 = crypto.createHash('md5').update(trackInfos.SNG_ID.toString(), 'ascii').digest('hex');
|
||||
let bfKey = '';
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
bfKey += String.fromCharCode(idMd5.charCodeAt(i) ^ idMd5.charCodeAt(i + 16) ^ SECRET.charCodeAt(i));
|
||||
}
|
||||
|
||||
return bfKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a deezer track.
|
||||
*
|
||||
* @param {Buffer} trackBuffer
|
||||
* @param {Object} trackInfos
|
||||
*
|
||||
* @return {Buffer}
|
||||
*/
|
||||
function decryptTrack(trackBuffer, trackInfos) {
|
||||
const blowFishKey = getBlowfishKey(trackInfos);
|
||||
|
||||
let decryptedBuffer = Buffer.alloc(trackBuffer.length);
|
||||
let chunkSize = 2048;
|
||||
let progress = 0;
|
||||
|
||||
while (progress < trackBuffer.length) {
|
||||
if ((trackBuffer.length - progress) < 2048) {
|
||||
chunkSize = trackBuffer.length - progress;
|
||||
}
|
||||
|
||||
let encryptedChunk = trackBuffer.slice(progress, progress + chunkSize);
|
||||
|
||||
// Only decrypt every third chunk and only if not at the end
|
||||
if (progress % (chunkSize * 3) === 0 && chunkSize === 2048) {
|
||||
let cipher = crypto.createDecipheriv('bf-cbc', blowFishKey, Buffer.from([0, 1, 2, 3, 4, 5, 6, 7]));
|
||||
cipher.setAutoPadding(false);
|
||||
|
||||
encryptedChunk = Buffer.concat([cipher.update(encryptedChunk), cipher.final()]);
|
||||
}
|
||||
|
||||
decryptedBuffer.write(encryptedChunk.toString('binary'), progress, encryptedChunk.length, 'binary');
|
||||
|
||||
progress += chunkSize;
|
||||
}
|
||||
|
||||
return decryptedBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the track, decrypt it and write it to a file.
|
||||
*
|
||||
@ -2150,7 +2090,7 @@ function downloadTrack(trackInfos, trackQualityId, saveFilePath, numberRetry = 0
|
||||
}).then((response) => {
|
||||
log.debug('Got download response for "track/' + trackInfos.SNG_ID + '"');
|
||||
|
||||
const decryptedTrackBuffer = decryptTrack(response, trackInfos);
|
||||
const decryptedTrackBuffer = encryptionService.decryptTrack(response, trackInfos);
|
||||
|
||||
resolve(decryptedTrackBuffer);
|
||||
}).catch((err) => {
|
||||
|
70
src/service/EncryptionService.js
Normal file
70
src/service/EncryptionService.js
Normal file
@ -0,0 +1,70 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
module.exports = class EncryptionService {
|
||||
|
||||
getSongFileName(trackInfos, trackQuality) {
|
||||
const step1 = [trackInfos.MD5_ORIGIN, trackQuality, trackInfos.SNG_ID, trackInfos.MEDIA_VERSION].join('¤');
|
||||
|
||||
let step2 = crypto.createHash('md5').update(step1, 'ascii').digest('hex') + '¤' + step1 + '¤';
|
||||
while (step2.length % 16 > 0) step2 += ' ';
|
||||
|
||||
return crypto.createCipheriv('aes-128-ecb', 'jo6aey6haid2Teih', '').update(step2, 'ascii', 'hex');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the blowfish key to decrypt the track
|
||||
*
|
||||
* @param {Object} trackInfos
|
||||
*/
|
||||
getBlowfishKey(trackInfos) {
|
||||
const SECRET = 'g4el58wc0zvf9na1';
|
||||
|
||||
const idMd5 = crypto.createHash('md5').update(trackInfos.SNG_ID.toString(), 'ascii').digest('hex');
|
||||
let bfKey = '';
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
bfKey += String.fromCharCode(idMd5.charCodeAt(i) ^ idMd5.charCodeAt(i + 16) ^ SECRET.charCodeAt(i));
|
||||
}
|
||||
|
||||
return bfKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a deezer track.
|
||||
*
|
||||
* @param {Buffer} trackBuffer
|
||||
* @param {Object} trackInfos
|
||||
*
|
||||
* @return {Buffer}
|
||||
*/
|
||||
decryptTrack(trackBuffer, trackInfos) {
|
||||
const blowFishKey = this.getBlowfishKey(trackInfos);
|
||||
|
||||
let decryptedBuffer = Buffer.alloc(trackBuffer.length);
|
||||
let chunkSize = 2048;
|
||||
let progress = 0;
|
||||
|
||||
while (progress < trackBuffer.length) {
|
||||
if ((trackBuffer.length - progress) < 2048) {
|
||||
chunkSize = trackBuffer.length - progress;
|
||||
}
|
||||
|
||||
let encryptedChunk = trackBuffer.slice(progress, progress + chunkSize);
|
||||
|
||||
// Only decrypt every third chunk and only if not at the end
|
||||
if (progress % (chunkSize * 3) === 0 && chunkSize === 2048) {
|
||||
let cipher = crypto.createDecipheriv('bf-cbc', blowFishKey, Buffer.from([0, 1, 2, 3, 4, 5, 6, 7]));
|
||||
cipher.setAutoPadding(false);
|
||||
|
||||
encryptedChunk = Buffer.concat([cipher.update(encryptedChunk), cipher.final()]);
|
||||
}
|
||||
|
||||
decryptedBuffer.write(encryptedChunk.toString('binary'), progress, encryptedChunk.length, 'binary');
|
||||
|
||||
progress += chunkSize;
|
||||
}
|
||||
|
||||
return decryptedBuffer;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user