Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
326 views
in Technique[技术] by (71.8m points)

nfc - Checksum Error while provisioning Android Lollipop

I get the message Couldn't use the admin app due to a checksum error. Contact your IT department when using the code below. Basically you have two Android Lollipop devices. One device is unprovisioned (Factory reset) and the other has this programming app on it. The programming app sends an NFC command to the unprovisioned device to tell it to start provisioning using the data you pass to it. There are three fields required (APK Location, APK file checksum, and package name) as per DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC.

The APK is getting downloaded. I'm checking my server logs and it's clearly coming from the device (AndroidDownloadManager is in the user agent).

According to DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM it is a SHA-1 checksum of the file. The checksum is not matching. I've tried many different formats of this checksum (hex, hex with spaces, uppercase/lowercase, base64, text) and I guess it's possible I missed a test.

Unfortunately, the Android Lollipop source is not yet available otherwise I would be checking there.

How do I fix this? Any thoughts?

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);
        }
    }
}

Note: This is using the latest Android L Developer Preview. I guess it is entirely possible that this feature isn't finished yet. Update: Actual release acts this way too.


APK: https://storage.googleapis.com/randy/DeviceOwnerCheck.apk
Checksum: FRaAsqdPSjp9nC5hKIU/ElPv+e4
Result: Using this URL and this checksum gives an error and doesn't even get to the encrypt device screen.


I also posted two applications to GitHub. One sends the NFC data to provision. The other is just an app to check if the app is device admin or device owner. Hopefully someone finds this useful. You'll need to modify the URL and the checksum if you want to build DeviceOwnerCheck yourself.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The hash code must be url safe. This converts and removes trailing padding

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...