Feb 8, 2010

Verify whether flash swf file is loaded from Facebook

This article describes how to verify that Flash object was loaded from Facebook web page.

There are official detailed instructions on facebook page you can find here:
http://wiki.developers.facebook.com/index.php/Fb:swf

Here are main points:

For security, this technique does not embed your secret key in your Flash app:
  1. Get all the parameters whose names start with fb_sig. (Do not include the fb_sig parameter itself.) In Flex use Application.application.parameters to do this.
  2. Strip the fb_sig_ prefix from all parameters.
  3. Create a string of the form param1=value1param2=value2param3=value3, etc., sorted by the names (not the values) of the parameters. Note: Do not use ampersands between the parameters.
  4. Separately pass this string and the fb_sig parameter itself to your server, where your secret key is stored.
  5. On your server, append your application secret key to the string that was passed in. The following is returned: param1=value1param2=value2param3=value3myappsecret
  6. On your server, create an MD5 hash of this string.
  7. On your server, compare the generated hash with the fb_sig parameter that was passed in. If they are equal, then your Flash object was loaded by Facebook.

After reading that article, many developers try to use fb_sig_ parameters which are listed here
and it doesn't work.
The right way to generate string from point 3 above is to use all parameters with prefix "fb_sig_" because those can be changed anytime by facebook.

Here is Actionscript 3 code that implements this technique:

private function encodeFlashVarsString(parameters:Object):String{
var keyArray:Array = new Array();
for (key in parameters) {
keyArray.push(key);
}
keyArray = keyArray.sort();
var hashString:String = "";
while (keyArray.length > 0) {
var key:String = keyArray.shift();
if (key != "fb_sig" && key.substring(0, 6) == "fb_sig") {
var param:String = parameters[key];
hashString += key.substr(7) + "=" + param;
}
}
return hashString;
}

You can acces parameters from loaderInfo field of stage or other MovieClips. For example:
parameters = stage.loaderInfo.parameters;


Now, you need to send generated hash string to your server where it will be merged with Facebook Application Secret Key and MD5 hash should be calculated. Then you need to compare MD5 code with fb_sig parameter to determine if swf file was loaded and run from Facebook page. So, don't forget to send "fb_sig" parameter to the server as well.

Here is server side java code that makes MD5 hash calculation and compares result with result received from client side.


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* Check if client application run from facebook page
* @param paramsString String generated on client side
* @param appSecretKey Your application's secrete key
* @param resHashString String we should receive after paramsString MD5 hash calculation
* @return true if swf file was loaded from Facebook page
*/

public static boolean checkHashString( String paramsString,
String appSecretKey,
String resHashString
) {
if(paramsString == null || resHashString == null){
return false;
}
try {
String srcString = paramsString + appSecretKey;
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] src = srcString.getBytes();
byte[] res = md5.digest(src);
String resStr = new BigInteger(1, res).toString(16);
return resStr.equals(resHashString);
} catch (NoSuchAlgorithmException ex) {
System.out.println("md5 exception:"+ex.getMessage());
}
return false;
}


Hope it is helpful article :)

No comments:

Post a Comment