-
-
Save HereOrCode/f5db7fd871699c67357c58ef893dcba6 to your computer and use it in GitHub Desktop.
a function to decrypt WA Media
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* this code is copied from https://github.com/open-wa/wa-decrypt-nodejs | |
* i just made it more simplified | |
*/ | |
const { default: axios } = require('axios'); | |
const crypto = require('crypto'); | |
const hkdf = require('futoin-hkdf'); | |
const atob = require('atob'); | |
const fixPadding = (data, expectedSize) => { | |
const padding = (16 - (expectedSize % 16)) & 0xf; | |
if (padding > 0) { | |
if ((expectedSize + padding) == data.length) { | |
// console.log(`trimmed: ${padding} bytes`); | |
data = data.slice(0, data.length - padding); | |
} else if ((data.length + padding) == expectedSize) { | |
// console.log(`adding: ${padding} bytes`); | |
const arr = new Uint16Array(padding).map(() => padding); | |
data = Buffer.concat([data, Buffer.from(arr)]); | |
} | |
} | |
// @ts-ignore | |
return Buffer.from(data, 'utf-8'); | |
}; | |
const hexToBytes = (hexStr) => { | |
const intArray = []; | |
for (let i = 0; i < hexStr.length; i += 2) { | |
intArray.push(parseInt(hexStr.substr(i, 2), 16)); | |
} | |
return new Uint8Array(intArray); | |
}; | |
const base64ToBytes = (base64Str) => { | |
const binaryStr = atob(base64Str); | |
const byteArray = new Uint8Array(binaryStr.length); | |
for (let i = 0; i < binaryStr.length; i++) { | |
byteArray[i] = binaryStr.charCodeAt(i); | |
} | |
return byteArray; | |
}; | |
const mediaTypes = { | |
IMAGE: 'Image', | |
VIDEO: 'Video', | |
AUDIO: 'Audio', | |
PTT: 'Audio', | |
DOCUMENT: 'Document', | |
STICKER: 'Image', | |
}; | |
const magix = (fileData, mediaKeyBase64, mediaType, expectedSize = '', mimetype = '') => { | |
const encodedHex = fileData.toString('hex'); | |
const encodedBytes = hexToBytes(encodedHex); | |
const mediaKeyBytes = base64ToBytes(mediaKeyBase64); | |
const info = `WhatsApp ${mediaTypes[mediaType.toUpperCase()] || mediaTypes[Object.keys(mediaTypes).filter((type) => mimetype.includes(type.toLowerCase()))[0]]} Keys`; | |
const hash = 'sha256'; | |
const salt = new Uint8Array(32); | |
const expandedSize = 112; | |
const mediaKeyExpanded = hkdf(mediaKeyBytes, expandedSize, { | |
salt, | |
info, | |
hash, | |
}); | |
const iv = mediaKeyExpanded.slice(0, 16); | |
const cipherKey = mediaKeyExpanded.slice(16, 48); | |
const decipher = crypto.createDecipheriv('aes-256-cbc', cipherKey, iv); | |
const decoded = decipher.update(encodedBytes); | |
const mediaDataBuffer = expectedSize ? fixPadding(decoded, expectedSize) : decoded; | |
return mediaDataBuffer; | |
}; | |
const decryptMedia = async (message) => { | |
const options = { | |
responseType: 'arraybuffer', | |
headers: { | |
'User-Agent': 'WhatsApp/2.16.352 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36', | |
DNT: 1, | |
'Upgrade-Insecure-Requests': 1, | |
origin: 'https://web.whatsapp.com/', | |
referer: 'https://web.whatsapp.com/', | |
}, | |
}; | |
const res = await axios.get(message.deprecatedMms3Url.trim(), options); | |
const buff = Buffer.from(res.data, 'binary'); | |
return magix(buff, message.mediaKey, message.type, message.size, message.mimetype); | |
}; | |
const message = { | |
type: 'image', | |
deprecatedMms3Url: 'https://mmg.whatsapp.net/v/t62.7118-24/32988171_775415480878877_6103136834163776922_n.enc?ccb=11-4&oh=01_AdS7iKRPVP9je_HosEutBTpM5s7jFPlWIK3WVz19bZM4xA&oe=647B3771&mms3=true', | |
directPath: '/v/t62.7118-24/32988171_775415480878877_6103136834163776922_n.enc?ccb=11-4&oh=01_AdS7iKRPVP9je_HosEutBTpM5s7jFPlWIK3WVz19bZM4xA&oe=647B3771', | |
staticUrl: '', | |
mimetype: 'image/jpeg', | |
caption: 'Kek punya @areta', | |
filehash: 'c4ovTdfcoO5LClgIPRJTnwzA+eUdGYIx670iLLlKiNU=', | |
encFilehash: '1jyLb2XbsTnca0CZZ+Du7Rux0xPeW75IJ80ChxUZDdA=', | |
size: 189236, | |
height: 1520, | |
width: 720, | |
mediaKey: 'b+Jq/CPv8E1PJy+S0FB9TD4gQGVpcoVFeSKzBqPUYZI=', | |
mediaKeyTimestamp: 1683209371, | |
body: '', | |
interactiveAnnotations: [], | |
scanLengths: [ | |
11842, | |
65657, | |
46750, | |
64987, | |
], | |
scansSidecar: {}, | |
isViewOnce: true, | |
}; | |
const fs = require('fs'); | |
decryptMedia(message).then((res) => fs.writeFileSync('img.jpeg', res)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment