Pokazywanie postów oznaczonych etykietą keytool jarsigner apk signature certificate. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą keytool jarsigner apk signature certificate. Pokaż wszystkie posty

niedziela, 24 kwietnia 2011

Converting release keys to debug

Tests in android are like applications. They are organized into apks. They are installed along with application under test.
For security reasons they both require to be signed by the same keystore.

If you use different key for the application and the test you will get error:

Test run failed: Permission Denial: starting instrumentation ComponentInfo{net.retsat1.starlab.test/android.test.InstrumentationTestRunner} from pid=305, uid=305 not allowed because package net.retsat1.starlab.test does not have a signature matching the target net.retsat1.starlabjava.lang.SecurityException: Permission Denial: starting instrumentation ComponentInfo{net.retsat1.starlab.test/android.test.InstrumentationTestRunner} from pid=305, uid=305 not allowed because package net.retsat1.starlab.test does not have a signature matching the target net.retsat1.starlab


During development cycle keys generated by eclipse are usually used. When you are starting to think about release you are preparing the build signed with release key.

In eclipse there is no automatic way to sign for release, so you probably hand over this to ant script or do the signing by hand.

Afterwards if you are lucky your test that had previously run successfully on debug mode will be still passing in release mode. If for some reason this is not true you want to debug your test with eclipse.

When you want to run test(s) against your new build you find that signatures of the test and release apk mismatch.

In eclipse you can set a custom keystore from menu

Windows -> Preferences -> Android - > Build


This unfortunately leads to a problem as you eclipse does not accept release keystore with an error: Keystore was tampered with, or password was incorrect.

To convert release key to debug one that will be acceptable for eclipse, you need to import keystore into new debug keystore with keytool from jdk. This is done with the following command.

keytool -importkeystore -v -srckeystore release.keystore -destkeystore custom-debug.keystore -srcstorepass release-pass -deststorepass android -srcalias release-key -destalias androiddebugkey -srckeypass release-pass -destkeypass android


Of course substitute passwords and alias of source keystore with the one used in creation of release keystore.

sobota, 29 stycznia 2011

Working with signatures in apk(s)

Our task in the job was to write some (robotium) test to the application(s) that we were given only apk-s and the debug.keystore.

We had to use the same debug.keystore to be able to run InstrumentationTestCase. When the keys didn't match we get an error similar to this:

java.lang.SecurityException: Permission Denial: starting instrumentation ComponentInfo{net.retsat1.starlab.test/android.test.InstrumentationTestRunner} from pid=4745, uid=4745 not allowed because package net.retsat1.starlab.test does not have a signature matching the target net.retsat1.starlab


The keys have changed in the course of time few times and we soon get into the mess of not being sure which debug keystore was used.

We had to find a way to check which certificate is used.

On android pages you can get some information about signing the apks with the certificates.

http://developer.android.com/guide/publishing/app-signing.html#cert

and about security model used

http://developer.android.com/guide/topics/security/security.html


First thing we tried is the

jarsigner -verify -verbose -certs net.retsat1.starlab-1.apk


which output is

sm 520 Sat Jan 22 23:11:20 CET 2011 res/layout/main.xml

X.509, CN=Android Debug, O=Android, C=US
[certificate is valid from 05.10.10 21:47 to 05.10.11 21:47]


this can be compared to the output of the same command on the apk we are sure with which certificate was signed and look at the validity time. However, this is not very convenient. It would be better to get some number that can be easily compared.

Keytool is capable of displaying a certificate finger print

keytool -keystore ~/.android/debug.keystore -storepass android -list


That gives the output

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

androiddebugkey, 2010-10-05, PrivateKeyEntry,
Certificate fingerprint (MD5): 32:BD:9C:D1:1A:8C:32:95:B1:4F:14:45:B4:5D:86:D6

Which is basically what we were looking for. Now we needed the same for the apk.

After examining some robotium tutorials and this script sign-debug-any-apk.sh we produced a semi-automated script (printfingerprint.sh) for that.


#!/bin/bash

if [ $# -lt 1 ]; then
echo -e "Prints certificate fingerprint of the given apk file.\nUsage: $0 file.apk"
exit 1
fi

APKFILE=`readlink -f $1`

TEMP=`mktemp -d`
cd $TEMP
jar xf $APKFILE
keytool -printcert -file META-INF/CERT.RSA | egrep "^\s+MD5|^\s+SHA"
rm $TEMP -rf


Semi automatic as we need to get the apk from the device first.


printfingerprint.sh ~/tmp3/net.retsat1.starlab-1.apk

which leads us to

MD5: 32:BD:9C:D1:1A:8C:32:95:B1:4F:14:45:B4:5D:86:D6
SHA1: C4:68:47:DD:BF:61:C5:03:27:08:96:1C:7A:75:E1:42:DD:EC:C8:F2

and we can verify if the certificate in apk(s) match.