Skip to content

Instantly share code, notes, and snippets.

@aperpen
Created March 8, 2019 17:20
Show Gist options
  • Save aperpen/18378731d8ef081c2f940d862ff40754 to your computer and use it in GitHub Desktop.
Save aperpen/18378731d8ef081c2f940d862ff40754 to your computer and use it in GitHub Desktop.
Decrypt Supercell storage_new.xml files
const crypto = require('crypto')
const fs = require('fs')
// Constants
const PACKAGE_NAME = 'com.supercell.clashroyale'
const AES_MODE_CBC = 'cbc'
const AES_MODE_ECB = 'ecb'
const AES_IV_KEY = 'fldsjfodasjifudslfjdsaofshaufihadsf'
class AESCipher {
constructor(key, mode = AES_MODE_CBC) {
this.mode = mode
this.bs = 16
const hash = crypto.createHash('sha256')
hash.update(key)
this.key = hash.digest()
this.ivKey = this.mode === AES_MODE_CBC && AES_IV_KEY.slice(0, this.bs)
}
decrypt(crypted) {
const decipher = crypto.createDecipheriv(`aes-256-${this.mode}`, this.key, this.ivKey || null)
const decrypted = decipher.update(crypted, 'base64', 'utf8')
return decrypted + decipher.final('utf8')
}
}
/* BUILDING THE KEY */
const keyMap = [102, 76, 120, 89, 66, 57, 77, 56, 52, 65, 98, 101, 117, 115, 69, 82, 77, 89, 57, 89, 70, 122, 86, 71]
let key = ''
for (let i = PACKAGE_NAME.length - 1; i > -1; i--) {
const i1 = PACKAGE_NAME.codePointAt(i)
const i2 = keyMap[i % keyMap.length]
key += String.fromCodePoint(((i1 ^ i2) & 0x1F) + 48)
}
/* PARSE XML FILE */
const xmlContent = fs.readFileSync('./storage_new.xml', 'utf-8')
const pairs = {}
const re = /<string name="([^"]+)">([^<]+)<\/string>/g
let match
do {
match = re.exec(xmlContent)
if (match) pairs[match[1]] = match[2]
} while (match)
const kCipher = new AESCipher(key, AES_MODE_ECB)
const vCipher = new AESCipher(key, AES_MODE_CBC)
for (let k in pairs) console.log(`[+] ${kCipher.decrypt(k)} = ${vCipher.decrypt(pairs[k])}`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment