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).
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.
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.
@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.
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.
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).
These AuthHandler
objects eventually use tryIntent()
to call startActivityForResult()
to invoke the Facebook app itself.
So, to sum up, the login process:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With