Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does facebook verify app authenticity with key hash?

Tags:

When developing an android app with facebook, you are required to upload the key hash of your app to their site. With this they claim that they are able to verify that the calls to their servers are actually made from your app.

I've read this question How does Facebook verifies mobile apps but it doesn't really provide the actual implentation of this. I've tried looking into the source code of the facebook library but couldn't figure it out.

Which data is sent out of the android app and under what encryption that can be verified against this hash in the server? Is the method implemented by facebook fail safe?

If it is, and the it can be implemented in any server I could use it to verify against my server that my apps haven't been recompiled with different code (Which tends to happen pretty often :( )


I'm currently implementing this idea in this way:

Signature[] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(),     PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs) {
    verifyInServer(sig.hashCode());
}

Where verifyInServer is pseudocode for the check made against the server with the stored value of the signatures. It has worked for now but I'm not sure that it's safe, and I'd rather check against a key hash (that its public) than this signature data (that I'm not really sure if it's private and not spoofable by the user).

like image 586
Javier Avatar asked Jun 02 '14 00:06

Javier


People also ask

How do you verify a mobile app?

If you're on the phone, you can connect to Wi-Fi to ensure you receive Mobile App Verification requests—even during a call. Check that your device is registered. In the app, go to Profile, Settings, then Security. From there, select “Mobile App Verification” for iOS or “Manage My Devices” for Android.

What is Android hash?

The key hash is a machine specific security check for authenticity. If you use multiple machines for development of the application, you need to add and save multiple key hash to your profile to authenticate every machine.


1 Answers

@Zbysek's answer is probably correct, in that's very likely that the Facebook app is the one that actually performs the verification. Without the source code of this app it's hard to know for sure, but we can infer some things from inspecting the source code of the Facebook API library project, in particular the login process as coded in the AuthorizationClient and Session classes.

  1. First of all, the client verifies that the Facebook application itself is correctly signed. This is expected, since you would not want to provide your login credentials to a fake app posing as Facebook. This is done in the NativeProtocol class (and also in the Facebook class, for the deprecated methods). This is the only mention of signatures in the API, so if there are additional verifications, they are either done by the Facebook app itself, or in the server.

  2. Session.open() eventually creates an AuthorizationClient which tries a series of possible handlers. One of them (the first used, if the SessionLoginBehavior allows it) is the Facebook application itself (for example with KatanaLoginDialogAuthHandler, but there are others).

  3. These AuthHandler objects eventually use tryIntent() to call startActivityForResult() to invoke the Facebook app itself.

So, to sum up, the login process:

  • verifies that the Facebook app is legit,
  • ends up calling an Activity inside the Facebook app,
  • calls it passing the FB application id, and some other data,
  • from an Activity inside your app, via startActivityForResult().

This is a key part, since activities started with startActivityForResult() (but not those started with startActivity()) can use getCallingActivity() to know the identity (package and class name) of its caller.

Therefore, the Facebook app could easily use this information to query the PackageManager, obtain your app's signature, pass that data along with the application id to the server, and validate that they match. And since the Facebook app is itself signed, your app can trust this result.

I admit this is all speculation, but seems plausible enough, given what we know :)

Unfortunately this also means that it's unlikely that this mechanism could be replicated for your own use of guaranteeing authenticity. Unless you are Facebook or Google (Google Play Services has a similar signature verification feature, e.g. for Maps) or can somehow ensure that a second app of yours will also be available on every device.

like image 66
matiash Avatar answered Sep 28 '22 06:09

matiash