The download_media python function does the decryption of an encrypted file using the axolotl.kdf.hkdfv3 python library.
However Whatsapp web does it using its own Javascript libraries.
Has anyone found a way of decrypting an encrypted media file using Javascript in wapi.js?
Which item in the Store object includes the decrypt function?
I found how to decrypt image data in Javascript. So let me share it:
This is the modified downloadFile function which returns an ArrayBuffer:
window.WAPI.downloadFile2 = function (url, done) {
let xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
done(xhr.response);
} else {
console.error(xhr.statusText);
}
} else {
console.log(err);
done(false);
}
};
xhr.open("GET", url, true);
xhr.responseType = 'arraybuffer';
//xhr.responseType = 'blob';
xhr.send(null);
};
And this is how you decrypt the downloaded ArrayBuffer:
WAPI.downloadFile2(msg.clientUrl, function(result) {
console.log("Encryption Key:" + msg.mediaKey);
console.log("Image Data:");
console.log(result);
Store.CryptoLib.decryptE2EMedia("IMAGE", result, msg.mediaKey, "image/jpeg").then(function(a) {
console.log("Decrypted Data:");
console.log(a);
console.log(a._blob);
let reader = new FileReader();
reader.readAsDataURL(a._blob);
reader.onload = function (e) {
console.log("FileReader result1:")
console.log(reader.result)
console.log("FileReader result2:")
console.log(reader.result.substr(reader.result.indexOf(',') + 1));
};
}).catch(function(e) {
console.log("Error: " + e);
});
});
To get the CryptoLib object add the following item to 'neededObjects' array:
{ id: "CryptoLib", conditions: (module) => (module.decryptE2EMedia) ? module : null },
I hope this may be useful to someone who needs it. :)
I'm not closing the issue so that it will be visible in the issues list.
@mukulhase
@postacik Does this mean, that it would be able to get the full sized image directly from javascript?
This would mean that there would be the possibility to create a version of webwhatsapi that won't rely on axalot-api
That's right. The example above does exactly what you describe.
I couldn't make it work to PTT media, but to work in any media, using the functions given by @postacik:
WAPI.processMediaMessage = (messageObj) => {
WAPI.download2(messageObj.clientUrl, (arrBuffer) => {
Store.CryptoLib.decryptE2EMedia(messageObj.type.toUpperCase(), arrBuffer,
messageObj.mediaKey, messageObj.mimetype)
.then((a) => {
let fr = new FileReader();
fr.readAsDataURL(a._forceToBlob());
fr.onloadend = () => {
let base64 = fr.result.split(',')[1];
messageObj.body = base64;
messageObj.content = base64;
}
});
});
}
But to remote browser this does not work. I think it's because the _WAPI.download2_ is async.
Do you guys have any idea to do this to a remote browser? Thanks!
Is it possible to do the same "offline"?
I mean if I have the localStorage that contaons the "encKey" and "key", how can I decrypt an encrypted file?
I know it's aes but I don't know the IV (if the key is key or encKey)
@postacik This was really useful, thankss
Im trying decrypt the images, but im receiving this error:
Console:
Encryption Key:XoCx4cwS6d/X5c5iOn0nOSkfEEqUZZumeDy8HVbGsqw=
Image Data:ArrayBuffer(114522) {}
Error: MediaEncryptionError: decrypt async, missing "payload"
Can someone help me ??
Most helpful comment
I found how to decrypt image data in Javascript. So let me share it:
This is the modified downloadFile function which returns an ArrayBuffer:
And this is how you decrypt the downloaded ArrayBuffer:
To get the CryptoLib object add the following item to 'neededObjects' array:
{ id: "CryptoLib", conditions: (module) => (module.decryptE2EMedia) ? module : null },I hope this may be useful to someone who needs it. :)
I'm not closing the issue so that it will be visible in the issues list.