安卓WebView加密内容

4
我有一个应用程序,使用Webview来显示内容,并且JavaScript调用是我的应用程序的控制器。为了提供一定程度的安全性,我混淆了代码。但这还不够,因为我希望加密HTML和JS文件,然后在运行时解密它们。我使用RC4算法加密这些资源,并将apk文件打包。在加载文件时,我解密JavaScript文件,加载它们,然后解密HTML文件并加载它。然而,这样做不起作用,因为Web内容会以“data:text/html”的形式显示消息,可能是暂时关闭或已永久移动等等。
我的问题是: 1.如何使位于资产文件夹中的HTML和JavaScript文件安全,以免被访问? 2.如果我的方法正确,是否有人知道我错在哪里?
谢谢!
以下是解密和加载资源的代码:
protected void loadWebContent() {
        checkEncryptionEnabled();
        loadJSFiles();
        logger.info("Loaded js ... going for html");
        loadAssetFile("www/index.html", "text/html");
    }

    private void loadJSFiles() {
        String[] jsFilesArray = { "app.js", "iscroll.js", "iui.js", "json.js" };
        for (String js : jsFilesArray) {
            loadAssetFile("www/js/" + js, "application/javascript");
        }
    }

    private void loadAssetFile(String filePath, String mimeType) {
        AssetManager assetMgr = getAssets();
        InputStream is = null;
        try {
            is = assetMgr.open(filePath);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] temp = new byte[512];
            int bytesRead = -1;
            while ((bytesRead = is.read(temp)) > 0) {
                baos.write(temp, 0, bytesRead);
            }
            byte[] encrypted = baos.toByteArray();
            String content = null;
            /**
             * true
             * */
            if (Config.ENCRYPTION_ENABLED) {
                byte[] decrypted = new RC4Encrypter("rc4_key").rc4(encrypted);
                content = new String(decrypted, "utf-8");
            } else {
                content = new String(encrypted, "utf-8");
            }

            /**
             * The webview to use
             * */
            if("application/javascript".equals(mimeType)) {
                webContent.loadUrl("javascript:" + content);
            } else {
                webContent.loadData(content, mimeType, "utf-8");
            }
        } catch (IOException ex) {
            logger.error(null, ex);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
    }

问题:在执行此操作时,您是否注意到延迟?我还构建了一个“编译器”,将所有内容压缩到最大并将css、js文件(使用Google闭包编译器编译)、图像(base64)等组合成一个文件。这个方法效果很好。文件大小为1.2MB。大小似乎没有问题,加载速度很快。但是当我像您一样使用加密时,将其解压缩到内存中是否是一个好主意?它会引入过多的开销吗? - Codebeat
2个回答

0

只要您能保持解密密钥的机密性,数据加密就没问题,但在上述代码中并非如此。硬编码的解密密钥可以在嵌入APK内部的DEX文件反编译后轻易被发现。

如果您想将应用程序逻辑隐藏在HTML和JavaScript文件中,并且该应用程序逻辑不需要离线功能,则可以将该应用程序逻辑的代码外包到服务器上。

从这里开始,您有两个选择:

  1. 每当需要时从服务器动态加载应用程序代码(并在客户端上运行应用程序代码)。
  2. 在服务器端实现应用程序逻辑,例如作为Web服务(并在服务器上运行应用程序代码,客户端仅知道如何调用Web服务)

对于您的第一个问题的简短回答是,没有一种方法或技术可以完美地保护您的应用程序。我建议您查看如何避免反向工程APK文件?以获取可能的保护方法概述。


0

找到了第二个问题的答案,而不是使用:webContent.loadData(content, mimeType, "utf-8"); 我使用了:webContent.loadDataWithBaseURL("file:///android_asset/www/", content, mimeType, "utf-8", null); 内容被正常显示了... 然而,第一个问题仍然存在,但考虑到一年多没有答案,我认为加密数据是可以接受的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接