..

Decrypting File encrypted by Monaca Plugin

Introduction

I stumble upon an android app developed using Monaca development framework with encrypted files. What is Monaca? from the official web monaca.io

Monaca makes HTML5 hybrid mobile app development with PhoneGap/ Cordova simple and easy. Monaca is the most open hybrid app development platform available and ready to be immediately plugged into your existing workflow and development environment. From Cloud IDE, CLI to debugger and remote online build, everything you need for your hybrid app development is here.

So basically it just another framework built on top of Cordova.

How do you determine the app is using Monaca framework? Normally, there will be traces of MonacaExtension.init in the MainActivity of the app.

trace of Monaca

As for Cordova-based app, the HTML code should be located in /assets/www/ folder. Upon opening the index.html, I found that the code is encrypted.

encrypted text

Upon investigation of the framework, and found out this is part of their offering for paid plan, to encrypt the HTML code using AES. Ref: https://docs.monaca.io/en/reference/power_plugins/html5_resource_encryption/

Encryption Analysis

The implementation of the encrypt/decrypt routine in the app present in the class io.monaca.plugins.encrypt

encrypt class

This the entry point for Encrypt plugin by Monaca, as you can see, it actually check if the autoDecrypt being boolean true, then the code will automatically set the Hash. Both variable coming from Config class in the plugin.

Basically, the autoDecrypt is set to True.

This portion of code will be called if the file is encrypted. Look at line(not sure if it actually line) 77 in the screenshot, the plugin check if the current file is actually encrypted. Encrypted monaca file have 8-bytes header. The header is {24, 8, 77, 69, 1, 13, 10, 0} (bytes), the magic header is from isEncrypted method inside the MonacaFile class.

Anyway, back to previous screenshot, the code flow is: if file is not encrypted, call mFileManager.getRawBytes(path, flagAsset) else try call mFileManage.getBytes(path, flagAsset)

The different here is getRawBytes vs getBytes. getRawBytes = read all file content getBytes = read all file content 8 bytes onward(because the encrypted file have 8-bytes magic header), and apply decryption.

Below are decryption routine code:

Config.Hash is the Key and first 16 bytes of the Config.Hash is the IV. Now we have the Key and IV, we should be able to decrypt the file. I wrote little python script to decrypt the encrypted file.

Decryption Code