在为Android Lollipop进行配置时出现校验和错误

13

当我使用以下代码时,收到消息由于校验和错误无法使用管理员应用程序。请联系您的IT部门。 基本上,您有两个Android Lollipop设备。一个设备未配置(出厂重置),另一个安装了此编程应用程序。 编程应用程序向未配置的设备发送NFC命令,告诉它使用您传递给它的数据开始配置。根据DevicePolicyManager的要求,需要三个字段(APK位置、APK文件校验和和包名称)。MIME_TYPE_PROVISIONING_NFC

APK正在下载。 我正在检查我的服务器日志,清楚地显示它来自该设备(AndroidDownloadManager在用户代理中)。

根据DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,它是文件的SHA-1校验和。 校验和不匹配。我尝试过许多不同格式的校验和(十六进制、带空格的十六进制、大写/小写、Base64、文本),但可能我错过了某个测试。

不幸的是,Android Lollipop源代码尚不可用,否则我会在那里检查。

我该如何解决这个问题? 有什么想法吗?

public class ProvisionerActivity extends Activity implements CreateNdefMessageCallback {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NfcAdapter mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        mNfcAdapter.setNdefPushMessageCallback(this, this);
    }

    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        try {
            Properties p = new Properties();
            p.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, "com.example.deviceownertest");
            p.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION, "http://example.com/DeviceOwnerTest.apk");
            p.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM, "19138948d8a607617971af724ffd08dd7eab771b");

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            OutputStream out = new ObjectOutputStream(bos);
            p.store(out, "");
            byte[] bytes = bos.toByteArray();

            NdefMessage msg = new NdefMessage(NdefRecord.createMime(DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, bytes));
            return msg;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

注意: 这是使用最新的Android L开发者预览版. 我猜这个功能可能还没有完全完成。 更新: 实际发布版本也是这样的。


APK: https://storage.googleapis.com/randy/DeviceOwnerCheck.apk
Checksum: FRaAsqdPSjp9nC5hKIU/ElPv+e4
Result: 使用这个URL和验证码会出错,甚至无法到达加密设备屏幕。


我还在GitHub上发布了两个应用程序。其中一个将NFC数据发送到配置文件中。另一个只是一个检查应用程序是否为设备管理员或设备所有者的应用程序。希望有人会发现这很有用。如果你想构建DeviceOwnerCheck,则需要修改URL和验证码。


你用这两个Github应用程序搞定了吗?我卡在同样的错误信息上,尝试了不同的下载URL和发布/调试版本。我的校验和看起来没问题,没有尾随空格,也没有特殊字符。你能告诉我你做了什么才让它工作吗? - Inneke De Clippel
@InnekeDeClippel,我现在能够使任何APK正常工作。请参考@Rob的答案。他的解决方案将校验和转换为URL安全字符串。它用“-”替换“+”,用“_”替换“/”,并完全删除填充(“=”)。还请注意@DeeV的评论,如果URL错误或下载失败,您将收到相同的错误消息,请检查您的Apache或IIS日志。祝好运! - Randy
非常感谢。经过多次尝试,我终于让它工作了。看起来我使用了错误的校验和。 - Inneke De Clippel
1
@Inneke,你能告诉我创建校验和的确切命令吗?因为我正在使用Rob建议的相同命令,但尚未成功。 - sunil jain
3
我使用的命令(请注意,这是在Windows上)是:输入" C:\Users\Inneke\Documents\Projects\KioskTest\app\app-debug.apk" | "C:\Program Files (x86)\GnuWin32\bin\openssl" dgst -binary -sha1 | "C:\Program Files (x86)\GnuWin32\bin\openssl" base64。这将输出类似于“ ABC9AbcABcabcaB0ABC+ABca1bc = ”的内容。我删除了“=”并将“+”替换为“-”,将“/”替换为“_”。因此,在应用程序中我使用的是:p.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,"ABC9AbcABcabcaB0ABC-ABca1bc")。请注意,您需要编写到您的.apk文件的路径,而不是密钥库的路径。 - Inneke De Clippel
谢谢@InnekeDeClippel,现在它已经可以工作了,实际上我是在APK网址方面犯了错误。 - sunil jain
3个回答

18

哈希码必须是url安全的。这将转换并删除尾部填充。

$ cat Something.apk | openssl dgst -binary -sha1 | openssl base64 | tr '+/' '-_' | tr -d '='

还应该注意,如果URL错误或下载失败,同样会出现相同的错误。 - DeeV
嗨,Rob,我遇到了同样的问题。在使用 NFC 安装设备所有者应用程序时出现校验和错误。我尝试了上面的命令来创建校验和,但它仍然出现相同的问题。请告诉我我做错了什么,以下是我的命令:cat /home/user/Downloads/adt-bundle-linux-x86_64-20140702/sdk/platform-tools/DevicePolicyDemo_2.1.apk | openssl dgst -binary -sha1 | openssl base64 | tr '+/' '-_' | tr -d '='。 - sunil jain
我遇到了同样的问题,我使用了以下命令:"C:\Program Files\Java\jdk-11.0.1\bin>keytool -printcert -jarfile "C:\Projects\MyEG\MyLogistics\app\build\outputs\apk\dev\debug\TestDPC_5001.apk" | "C:\Program Files\Git\usr\bin\openssl.exe" dgst -binary -sha1 | "C:\Program Files\Git\usr\bin\openssl.exe" base64 | tr '+/' '-_' | tr -d '='",但是它给了我一个错误提示:"tr" 不是内部或外部命令。那么我在哪里可以找到 "tr" 命令呢? - Mudassir Khan
当我使用以下命令时 C:\Program Files\Java\jdk-11.0.1\bin>keytool -printcert -jarfile "C:\Projects\MyEG\MyLogistics\app\build\outputs\apk\dev\debug\TestDPC_5001.apk" | "C:\Program Files\Git\usr\bin\openssl.exe" dgst -binary -sha1 | "C:\Program Files\Git\usr\bin\openssl.exe" base64,没有使用tr命令,因此它给出的值与示例中的值不同。那么这里缺少什么呢? - Mudassir Khan

6
似乎校验和中的特殊字符有问题。我已经成功地使用了我的apk文件,但校验和没有任何特殊字符。当我尝试使用您的apk文件时,我得到了同样的错误。请尝试重新创建apk,直到它不包含特殊字符,然后它就应该可以工作了。
我猜测可能存在某种缺失特殊字符转义的情况。

我曾经也遇到了你最初的那个问题,直到我采纳了Yuichi的解决方案。 - Rob
就是特殊字符的问题!我反复编译了几次,直到生成的 APK 校验和不包含任何特殊字符。真奇怪。但是,我很想知道使任何 APK 正常运行的正确方法是什么。 - Randy
是的,这很奇怪,我猜应该有一些方法来正确转义特殊字符。 - Rob

2

以下是获取哈希码的命令。

$ cat Something.apk | openssl dgst -binary -sha1 | openssl base64

此外,删除任何尾部填充(=)。

2
不幸的是,这给了我与之前相同的结果。校验和不匹配。 - Randy
我更新了我的问题,并附上了我使用的APK链接。同时,我还添加了两个应用程序的github链接(一个用于推送NFC数据,另一个是实际应用程序)。 - Randy

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