Skip to content

Instantly share code, notes, and snippets.

@zaksabeast
Last active August 25, 2024 21:25
Show Gist options
  • Save zaksabeast/e031a6512cb89de42aea70a8ca674619 to your computer and use it in GitHub Desktop.
Save zaksabeast/e031a6512cb89de42aea70a8ca674619 to your computer and use it in GitHub Desktop.
Pokemon Home Mobile App API Documentation
const crypto = require('crypto');
const zlib = require('zlib');
const util = require('util');
const gunzip = util.promisify(zlib.gunzip);
const decrypt = (data, key, iv) => {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
const decrypted = decipher.update(data);
return Buffer.concat([decrypted, decipher.final()]);
};
const reverseSubstring = (str, start, length) => {
return str.substr(start, length).split('').reverse().join('');
};
/**
* Decrypts an API POST request/response body
* @param {string} cryptoString1 String to derive key and iv found in the app
* @param {string} cryptoString2 String to derive key and iv found in the app
* @param {string} b64EncryptedBody API POST request/resposne body
*/
const decryptPOSTBody = async (cryptoString1, cryptoString2, b64EncryptedBody) => {
const encryptedBuf = Buffer.from(b64EncryptedBody, 'base64');
const stringOffset = parseInt(encryptedBuf.toString('utf8').substr(0, 2), 16);
const aesKey =
reverseSubstring(cryptoString1, 0, stringOffset) +
reverseSubstring(cryptoString2, stringOffset);
const aesIVPart1 = reverseSubstring(cryptoString2, 0, stringOffset);
const aesIVPart2 = reverseSubstring(cryptoString1, stringOffset);
const aesIV = (aesIVPart1 + aesIVPart2 + aesIVPart1 + aesIVPart2).substr(stringOffset, 16);
const decryptedData = decrypt(encryptedBuf.slice(2), aesKey, aesIV).toString('utf8');
const parsedData = JSON.parse(decryptedData);
// This works when the path contains /auth/
// TODO - this also needs decrypting for other paths
if (parsedData.pm) {
try {
const unzippedPm = await gunzip(Buffer.from(parsedData.pm, 'base64'));
parsedData.pm = JSON.parse(unzippedPm.toString('utf8'));
} catch (e) {
// Silently fail for now
}
}
return parsedData;
};
const [node, script, cryptoString1, cryptoString2, b64EncryptedBody] = process.argv;
if (process.argv.length === 5) {
decryptPOSTBody(cryptoString1, cryptoString2, b64EncryptedBody)
.then(console.log)
.catch((err) => console.error('Error!', err));
} else {
console.log(`Usage: ${node} ${script} cryptoString1 cryptoString2 b64EncryptedBody`);
}
@luluc00222
Copy link

Hello! Where can I find "cryptoString1" and "cryptoString2" ? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment