首页 > 解决方案 > 仅允许在 Android 中侧载选定的应用程序

问题描述

我正在尝试为媒体设备自定义 Android。我们从制造商那里获得了固件,它基于 Android 7,稍作修改。

我们想做的一件事是将设备上的应用程序安装限制为仅限某些应用程序。我们不会在设备上安装任何应用商店,例如 Google Play。我们将构建固件并将所有应用程序安装到我们车间的设备上并交付给客户。未来,我们可能希望通过 OTA 或某些机制在设备上安装更多应用程序。

我们希望禁止客户通过 USB 端口侧载其他应用程序。我们创建了一个文件(例如 whitelisted_apps.txt),其中包含所有已批准应用名称的列表,例如 -

com.mycompany.android.app1
com.mycompany.android.app2
com.ourpartner.android.appx

我们调整了 AOSP 的 PackageInstaller 应用程序,以便当通过文件浏览器打开 *.APK 文件并调用 PackageInstallerActivity.java 中的方法时,它会将要安装的应用程序的名称与 whitelisted_apps.txt 中的名称进行比较,并如果未找到该名称,则不允许安装新应用程序。它正在工作。

现在,我们想进一步改进它,因为 whitelisted_apps.txt 可以被操纵。有些人建议使用 sqlite 来保留列表。我们不确定这是否是最好的解决方案。

有些人建议使用证书和签名,我们认为这是一个比其他解决方案更好的解决方案。我们将使用我们的密钥对要安装在设备上的所有应用程序进行签名。当一个 *.APK 文件被侧载时,PackageInstaller 将获取 APK 的签名并与我们的进行比较。如果它们匹配,则可以旁加载应用程序。

我们关注了这个优秀的资源:SignatureCheck.java。它与硬编码的 APP_SIGNATURE 一起工作。我们目前有这个:

public boolean validateAppSignature() throws NameNotFoundException {
    boolean sigMatch = false;
    String APP_SIGNATURE = "123456784658923C4192E61B16999";
    PackageInfo packageInfo3 = mPm.getPackageInfo(
            getPackageName(), PackageManager.GET_SIGNATURES);

    try {
        for (Signature signature : packageInfo3.signatures) {
            // SHA1 the signature
            String sha1 = getSHA1(signature.toByteArray());
            Log.i(TAG, "got this SHA1 of the signature ... "+sha1);
            // check if it matches hardcoded value
            sigMatch = APP_SIGNATURE.equals(sha1);
            if (sigMatch){
                return sigMatch;  
            }
        }
    } catch (Exception e) {
            e.printStackTrace();
        }

    return false;
}

只是我们不知道如何在现实世界中做到这一点。当我们使用 OTA 构建、安装应用程序或发布时,我们使用我们的私钥对这些应用程序进行签名,然后在设备(PackageInstaller 应用程序)上,我们将证书的 SHA1 签名硬编码为 APP_SIGNATURE 以便我们可以比较?还有其他想法吗?

太感谢了。

标签: androiddigital-signatureandroid-source

解决方案


似乎您正在努力部分关闭侧载。使用设备所有者完全关闭安装,只需预加载您想要的应用程序。或者让它唯一可以安装的应用程序是您自己的下载器,它只查看您的服务器。


推荐阅读