How to restrict access to app files in internal storage in cordova android?

Is it possible to prevent data in app's folder in internal storage from being accessed by a malicious user who gains physical access to the device and roots the device? For eg: I have set android:debuggable - false in android manifest and even disabled allowBackup to false. But if someone steals the device and roots it, they would be able to take the files from internal storage. Is it possible to prevent it? Thanks in advance and any help would be appreciated.

2 answers

  • answered 2018-11-08 10:04 Alesandro Giordano

    You can't block access for routed devices, but I advise you to encrypt your files

  • answered 2018-11-08 10:44 Alesandro Giordano

    My class is Crypter.java, copy this code into them

    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    /**
     * Created by Alessandro Giordano on 23/02/2018.
     *
     * This class encrypt e decript bytes array, you can generate or replicate your credencals (public & private key)
     * or generate them. To decrypt you need the same credentials generated by the same KeyPair.
     */
    public class Crypter {
    
    //KEY FACTORY
    public final String KEYFACTORY_RSA = "RSA";
    public final String KEYFACTORY_DH = "DH";
    public final String KEYFACTORY_DSA = "DSA";
    public final String KEYFACTORY_EC = "EC";
    public final String KEYFACTORY_X509 = "X.509";
    
    
    //AES
    public final String CHIPERINSTANCE_AES_CBC_ISO10126PADDING = "AES/CBC/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_CBC_NOPADDING = "AES/CBC/NoPadding";
    public final String CHIPERINSTANCE_AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_CBF_ISO10126PADDING = "AES/CBF/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_CBF_NOPADDING = "AES/CBF/NoPadding";
    public final String CHIPERINSTANCE_AES_CBF_PKCS5PADDING = "AES/CBF/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_CTR_ISO10126PADDING = "AES/CTR/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_CTR_NOPADDING = "AES/CTR/NoPadding";
    public final String CHIPERINSTANCE_AES_CTR_PKCS5PADDING = "AES/CTR/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_CTS_ISO10126PADDING = "AES/CTS/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_CTS_NOPADDING = "AES/CTS/NoPadding";
    public final String CHIPERINSTANCE_AES_CTS_PKCS5PADDING = "AES/CTS/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_ECB_ISO10126PADDING = "AES/ECB/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_ECB_NOPADDING = "AES/ECB/NoPadding";
    public final String CHIPERINSTANCE_AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_OFB_ISO10126PADDING = "AES/OFB/ISO10126Padding";
    public final String CHIPERINSTANCE_AES_OFB_NOPADDING = "AES/OFB/NoPadding";
    public final String CHIPERINSTANCE_AES_OFB_PKCS5PADDING = "AES/OFB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES_GCM_NOPADDING = "AES/GCM/NOPADDING";
    
    
    //AES-128
    public final String CHIPERINSTANCE_AES128_CBC_NOPADDING = "AES_128/CBC/NoPadding";
    public final String CHIPERINSTANCE_AES128_CBC_PKCS5PADDING = "AES_128/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES128_ECB_NOPADDING = "AES_128/ECB/NoPadding";
    public final String CHIPERINSTANCE_AES128_ECB_PKCS5PADDING = "AES_128/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES128_GCM_NOPADDING = "AES_128/GCM/NoPadding";
    
    
    //AES-256
    public final String CHIPERINSTANCE_AES256_CBC_NOPADDING = "AES_256/CBC/NoPadding";
    public final String CHIPERINSTANCE_AES256_CBC_PKCS5PADDING = "AES_256/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES256_ECB_NOPADDING = "AES_256/ECB/NoPadding";
    public final String CHIPERINSTANCE_AES256_ECB_PKCS5PADDING = "AES_256/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_AES256_GCM_NOPADDING = "AES_256/GCM/NoPadding";
    
    
    //ARC4
    public final String CHIPERINSTANCE_ARC4_ECB_NOPADDING = "ARC4/ECB/NoPadding";
    
    
    //BLOWFISH
    public final String CHIPERINSTANCE_BLOWFISH_CBC_ISO10126PADDING =    "BLOWFISH/CBC/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_CBC_NOPADDING =          "BLOWFISH/CBC/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_CBC_PKCS5PADDING =       "BLOWFISH/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_BLOWFISH_CBF_ISO10126PADDING =    "BLOWFISH/CBF/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_CBF_NOPADDING =          "BLOWFISH/CBF/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_CBF_PKCS5PADDING =       "BLOWFISH/CBF/PKCS5Padding";
    
    public final String CHIPERINSTANCE_BLOWFISH_CTR_ISO10126PADDING =    "BLOWFISH/CTR/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_CTR_NOPADDING =          "BLOWFISH/CTR/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_CTR_PKCS5PADDING =       "BLOWFISH/CTR/PKCS5Padding";
    
    public final String CHIPERINSTANCE_BLOWFISH_CTS_ISO10126PADDING =    "BLOWFISH/CTS/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_CTS_NOPADDING =          "BLOWFISH/CTS/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_CTS_PKCS5PADDING =       "BLOWFISH/CTS/PKCS5Padding";
    
    public final String CHIPERINSTANCE_BLOWFISH_ECB_ISO10126PADDING =    "BLOWFISH/ECB/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_ECB_NOPADDING =          "BLOWFISH/ECB/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_ECB_PKCS5PADDING =       "BLOWFISH/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_BLOWFISH_OFB_ISO10126PADDING =    "BLOWFISH/OFB/ISO10126Padding";
    public final String CHIPERINSTANCE_BLOWFISH_OFB_NOPADDING =          "BLOWFISH/OFB/NoPadding";
    public final String CHIPERINSTANCE_BLOWFISH_OFB_PKCS5PADDING =       "BLOWFISH/OFB/PKCS5Padding";
    
    
    //DES
    public final String CHIPERINSTANCE_DES_CBC_ISO10126PADDING =    "DES/CBC/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_CBC_NOPADDING =          "DES/CBC/NoPadding";
    public final String CHIPERINSTANCE_DES_CBC_PKCS5PADDING =       "DES/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DES_CBF_ISO10126PADDING =    "DES/CBF/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_CBF_NOPADDING =          "DES/CBF/NoPadding";
    public final String CHIPERINSTANCE_DES_CBF_PKCS5PADDING =       "DES/CBF/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DES_CTR_ISO10126PADDING =    "DES/CTR/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_CTR_NOPADDING =          "DES/CTR/NoPadding";
    public final String CHIPERINSTANCE_DES_CTR_PKCS5PADDING =       "DES/CTR/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DES_CTS_ISO10126PADDING =    "DES/CTS/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_CTS_NOPADDING =          "DES/CTS/NoPadding";
    public final String CHIPERINSTANCE_DES_CTS_PKCS5PADDING =       "DES/CTS/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DES_ECB_ISO10126PADDING =    "DES/ECB/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_ECB_NOPADDING =          "DES/ECB/NoPadding";
    public final String CHIPERINSTANCE_DES_ECB_PKCS5PADDING =       "DES/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DES_OFB_ISO10126PADDING =    "DES/OFB/ISO10126Padding";
    public final String CHIPERINSTANCE_DES_OFB_NOPADDING =          "DES/OFB/NoPadding";
    public final String CHIPERINSTANCE_DES_OFB_PKCS5PADDING =       "DES/OFB/PKCS5Padding";
    
    
    //DESEDE
    public final String CHIPERINSTANCE_DESede_CBC_ISO10126PADDING =    "DESede/CBC/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_CBC_NOPADDING =          "DESede/CBC/NoPadding";
    public final String CHIPERINSTANCE_DESede_CBC_PKCS5PADDING =       "DESede/CBC/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DESede_CBF_ISO10126PADDING =    "DESede/CBF/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_CBF_NOPADDING =          "DESede/CBF/NoPadding";
    public final String CHIPERINSTANCE_DESede_CBF_PKCS5PADDING =       "DESede/CBF/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DESede_CTR_ISO10126PADDING =    "DESede/CTR/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_CTR_NOPADDING =          "DESede/CTR/NoPadding";
    public final String CHIPERINSTANCE_DESede_CTR_PKCS5PADDING =       "DESede/CTR/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DESede_CTS_ISO10126PADDING =    "DESede/CTS/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_CTS_NOPADDING =          "DESede/CTS/NoPadding";
    public final String CHIPERINSTANCE_DESede_CTS_PKCS5PADDING =       "DESede/CTS/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DESede_ECB_ISO10126PADDING =    "DESede/ECB/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_ECB_NOPADDING =          "DESede/ECB/NoPadding";
    public final String CHIPERINSTANCE_DESede_ECB_PKCS5PADDING =       "DESede/ECB/PKCS5Padding";
    
    public final String CHIPERINSTANCE_DESede_OFB_ISO10126PADDING =    "DESede/OFB/ISO10126Padding";
    public final String CHIPERINSTANCE_DESede_OFB_NOPADDING =          "DESede/OFB/NoPadding";
    public final String CHIPERINSTANCE_DESede_OFB_PKCS5PADDING =       "DESede/OFB/PKCS5Padding";
    
    
    //RSA
    public final String CHIPERINSTANCE_RSA_ECB_NOPADDING =             "RSA/ECB/NoPadding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPPADDING =           "RSA/ECB/OAEPPadding";
    public final String CHIPERINSTANCE_RSA_ECB_PKCS1PADDING =          "RSA/ECB/PKCS1Padding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPSHA1MGF1Padding =    "RSA/ECB/OAEPwithSHA-1andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPSHA256MGF1Padding =    "RSA/ECB/OAEPwithSHA-256andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPSHA224MGF1Padding =    "RSA/ECB/OAEPwithSHA-224andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPSHA384MGF1Padding =    "RSA/ECB/OAEPwithSHA-384andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_ECB_OAEPSHA512MGF1Padding =    "RSA/ECB/OAEPwithSHA-512andMGF1Padding";
    
    public final String CHIPERINSTANCE_RSA_NONE_NOPADDING =                  "RSA/NONE/NoPadding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPPADDING =                "RSA/NONE/OAEPPadding";
    public final String CHIPERINSTANCE_RSA_NONE_PKCS1PADDING =               "RSA/NONE/PKCS1Padding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPSHA1MGF1Padding =        "RSA/NONE/OAEPwithSHA-1andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPSHA256MGF1Padding =      "RSA/NONE/OAEPwithSHA-256andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPSHA224MGF1Padding =      "RSA/NONE/OAEPwithSHA-224andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPSHA384MGF1Padding =      "RSA/NONE/OAEPwithSHA-384andMGF1Padding";
    public final String CHIPERINSTANCE_RSA_NONE_OAEPSHA512MGF1Padding =      "RSA/NONE/OAEPwithSHA-512andMGF1Padding";
    
    public KeyPair keyPair;
    public byte[] publicKey;
    public byte[] privateKey;
    
    /**
     *
     * @param publicKey byte[]
     * @param privateKey byte[]
     */
    public Crypter(byte[] publicKey, byte[] privateKey, KeyPair keyPair) {
        this.keyPair = keyPair;
        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }
    
    /**
     *
     * @param publicKey byte[]
     * @param privateKey byte[]
     */
    public Crypter(byte[] publicKey, byte[] privateKey) {
        this.keyPair = null;
        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }
    
    public Crypter(){
        this.keyPair = generateKeyPair();
        assert keyPair != null;
        this.publicKey = generatePublicKey();
        this.privateKey = generatePrivateKey();
    }
    
    /**
     *
     * @param inpBytes byte[]
     * @param keyFactor String
     * @param chiperInstance Stirng
     * @return byte[]
     */
    public byte[] encrypt(byte[] inpBytes, String keyFactor, String chiperInstance){
        try {
            KeyFactory kf = KeyFactory.getInstance(keyFactor); // KEYFACTOR_RSA
            //PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
            PublicKey pbk = kf.generatePublic(new X509EncodedKeySpec(this.publicKey));
            String xForm = chiperInstance; //CHIPERINSTANCE_RSA_ECB_PKCS1PADDING
            Cipher cipher = Cipher.getInstance(xForm);
            cipher.init(Cipher.ENCRYPT_MODE, pbk);
            return cipher.doFinal(inpBytes);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     *
     * @param inpBytes byte[]
     * @param keyFactor String
     * @param chiperInstance String
     * @return byte[]
     */
    public byte[] decrypt(byte[] inpBytes, String keyFactor, String chiperInstance){
    
        try {
            KeyFactory kf = KeyFactory.getInstance(keyFactor); // or "EC" or whatever
            PrivateKey pvk = kf.generatePrivate(new PKCS8EncodedKeySpec(this.privateKey));
            String xForm = chiperInstance;
            Cipher cipher = Cipher.getInstance(xForm);
            cipher.init(Cipher.DECRYPT_MODE, pvk);
    
            return cipher.doFinal(inpBytes);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     *
     * @return KeyPair
     */
    private KeyPair generateKeyPair(){
        KeyPairGenerator kpg;
        KeyPair key;
        try {
            kpg = KeyPairGenerator.getInstance(KEYFACTORY_RSA);
            kpg.initialize(1000); // The size of the key
            key = kpg.generateKeyPair();
    
            return key;
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return null;
    }
    
    /**
     *
     * @return byte[]
     */
    private byte[] generatePublicKey(){
        PublicKey key = this.keyPair.getPublic();
        return key.getEncoded();
    }
    
    /**
     *
     * @return byte[]
     */
    private byte[] generatePrivateKey(){
        PrivateKey key = this.keyPair.getPrivate();
        return key.getEncoded();
    }
    }
    

    And than this is an example to use Crypter class:

        //CRYPTER CLASS TEST
    
        Crypter crypter = new Crypter();
    
        byte[] encrypted = crypter.encrypt("Hey how are you".getBytes(), crypter.KEYFACTORY_RSA, crypter.CHIPERINSTANCE_RSA_ECB_PKCS1PADDING);
    
        byte[] base64enc = Base64.encodeBase64(encrypted);
    
        System.out.println(new String(base64enc));
        System.out.println("");
    
        FileWriterUtil.getOutputStramWriter("F://filecrypt.txt", base64enc);
    
        String readed = FileReaderUtil.getBuffederString("F://filecrypt.txt");
    
        System.out.println(readed);
    
    
        for (int i = 0; i<encrypted.length; i++){
            if(Byte.compare(encrypted[i], Base64.decodeBase64(readed.getBytes())[i]) != 0) {
                System.out.println(encrypted[i] + "--" + readed.getBytes()[i]);
    
            }
        }
    
        System.out.println(encrypted.length + "--" + Base64.decodeBase64(readed.getBytes()).length);
    
        Crypter decrpter = new Crypter(crypter.publicKey, crypter.privateKey);
    
    
        byte[] decrypted = decrpter.decrypt(Base64.decodeBase64(readed.getBytes()), crypter.KEYFACTORY_RSA, crypter.CHIPERINSTANCE_RSA_ECB_PKCS1PADDING);
    
        System.out.println(new String(decrypted));
    

    Example first encrypts the string to byte[] and encode it in Base64 to write it to a .txt file, than does the reverse proccess to decrypt the encoded string