9

I am currently developing RPC services for developers to use, but would like to make sure that I can distinguish between another app's debug key and their public key. Is there a way to check another app's key and tell whether it is a debug key and NOT a published app key?

The purpose of this is to be able to tell when their app is in development or release status, as I need to be able to tell whether they should be accessing my dev server or my production server.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Fuzzical Logic
  • 12,947
  • 2
  • 30
  • 58

2 Answers2

5

By default the androiddebugkey used by Eclipse (for instance) has a notAfter date & time that is at most 1 year in the future - such a short value is not accepted by the Android Market - you could use that to differentiate between developer signed builds? Or .. you could just check the publickey that the app uses - have them sign the RPC requests with the android.content.pm.Signature of their app?

PackageInfo pkgInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);

for (Signature appSignature : pkgInfo.signatures) {
    // javax.security - NOT java.security!
    X509Certificate appCertificate = X509Certificate.getInstance(appSignature.toByteArray());
    // appCertificate.getNotAfter() can give you the date & time the cert expires
    // appCertificate.getPublicKey() can give you the public key you sign the RPC requests with.
    // appCertificate.getSubjectDN() will give you a Principal named "CN=Android Debug,O=Android,C=US" for any debug certificate that hasn't been handcrafted by the developer.
}
Jens
  • 16,853
  • 4
  • 55
  • 52
  • Thank you for helping! Its been so long that I had almost given up. The issue here is that the key is "by default" 1 year. I have set my debug keys for 25 years... This is why I need to be able to tell the difference. Any thoughts? – Fuzzical Logic Oct 11 '11 at 15:40
  • I think this is the right track. The getSubjectDN() is definitely a possibility. Can you tell me where you found this information, so I may research it some more? – Fuzzical Logic Oct 11 '11 at 15:46
  • After doing some further research with this guidance, I came up with an effective solution. It is multi-part, but accounts for as many circumstances as possible. First is checking the date. Then, the SubjectDN. Finally, on another failure, I match the Public Key to a Market Query. Certainly, not even close to a full solution, but accommodates the majority of my need. Thanks again for this awesome information. – Fuzzical Logic Oct 11 '11 at 21:50
  • Yeah, its unfortunately very common for people to tweak their keys (at least after the confusion when the first one expires) - or even worse, shove the production key into their debug keystore (.. horrific idea). – Jens Oct 12 '11 at 06:22
4
static final String DEBUGKEY = 
      " key ";    


public static boolean signedWithDebugKey(Context context, Class<?> cls) 
{
    boolean result = false;
    try {
        PackageInfo pinfo = context.getPackageManager().getPackageInfo("your package name",PackageManager.GET_SIGNATURES);
        Signature sigs[] = pinfo.signatures;

        Log.d(TAG,sigs[0].toCharsString());

        if (DEBUGKEY.equals(sigs[0].toCharsString())) {
            result = true;
            Log.d(TAG,"package has been signed with the debug key");
        } else {
            Log.d(TAG,"package signed with a key other than the debug key");
        }

    } catch (android.content.pm.PackageManager.NameNotFoundException e) {
        return false;
    }

    return result;

} 

Run this code first time with debugkey, this will alway return false, but you'll get the encoded key in the Logcat. Copy that encoded key, and replace value " key " of DEBUGKEY, and it will work fine.

xtr
  • 5,870
  • 1
  • 21
  • 23
  • You need to unpack the signature, using for instance javax.security.X509Certificate - sigs[0].toCharsString() doesn't return "androiddebugkey", it returns a large hex-encoded string. – Jens Oct 03 '11 at 09:12
  • 1
    static final String DEBUGKEY = " key "; This line seems to insinuate that I already know the debug key, am I correct? If I am, I cannot possibly know the debug key as it is provided by another developer. The way my API works is that for a debug app it is free for use with testing, but for a published app, the developer must pay a minimal fee to integrate. It is essential that I know whether the key is debug or published without knowing what the key is. – Fuzzical Logic Oct 11 '11 at 15:42
  • yes, this way can only use if you use it personally and seem not good answer. – xtr Oct 12 '11 at 02:28