Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Flickr API for Windows Phone 7 – Part 2 – The Core – Signature

09.24.2010
| 10399 views |
  • submit to reddit

Now that I discussed the basics of Flickr API, I want to step straight into core development. No UI for now – just the background functionality – the engine behind the application. And the first is getting the user to authorize the application to be used with his account.

As you probably remember from my previous article, once you configured the registered application, you obtained an authentication URL. Before the user will be able to use the functionality provided by the application, he needs to navigate to that URL and authorize the application to use his/her account data.

Since this is a mobile application, once the user authorizes the app, he will see a code that he is supposed to enter in the mobile application:

This code is called the mini token - it will be used to generate the full token that will later on allow us to call other methods in the context of the mobile application. Before going any further with generated the full token, I must mention that most of the API calls are signed.

An API signature is another security measure that ensures the fact that the application can have access to specific data and is using valid API endpoints. The signature is generated using an interesting algorithm. Here is how it goes.

Every API call is executed by creating a web request to the Flickr API endpoint with specific parameters. For the simplest of the methods, these parameters include the method name, the API key and the signature (an optional parameter is the returned data format – I will be using JSON for pretty much everything here).
So a basic request would be look like this:

http://api.flickr.com/services/rest/?method=FLICKR_API_METHOD&api_sig=GENERATED_SIGNATURE&api_key=API_KEY&format=json

The signature basically represents all parameters and your secret key (not to be confused with the API key) you obtained on registering your application as an MD5 hash. The steps to generate the signature are the following:

1.    Get all parameters and their values
2.    Arrange them in alphabetical order (by the parameter name)
3.    Concatenate every parameter and their value (without the ‘=’ sign)
4.    Put the secret key as the prefix to the existing concatenated string
5.    Generate the MD5 hash for the complete string

Applied, to my sample URL I used above, the steps will be executed like this:

1.    method=FLICKR_API_METHOD, api_key=API_KEY, format=json
2.    api_key=API_KEY, format=json, method=FLICKR_API_METHOD
3.    api_keyAPI_KEYformatjsonmethodFLICKR_API_METHOD
4.    SECRET_KEYapi_keyAPI_KEYformatjsonmethodFLICKR_API_METHOD
5.    b99802319bf5fc65d6d0ce77d7a50a89

Now this is all good in theory, but I need to actually implement this in my Windows Phone 7 application. One important thing to remember here is that there is no built-in functionality to generate a MD5 in Windows Phone 7 SDK. The developer has two choices here – either to develop his own method to generate the MD5 hash based on the algorithm description (I will cover this later on) or delegate the hashing to a WCF service. For now, I am just going to delegate this process to a WCF service – the application needs Internet access to work anyway, so it’s not an additional problem if you’re going to introduce a reference to another web service.

In Visual Studio, create a simple WCF Service Application:

First of all, rename the existing interface to IHash and define it like this:

[ServiceContract]
public interface IHash
{
    [OperationContract]
    string GetHashString (string text);
}

There will simply be one method that will obtain the string that needs to be hashed and will return the formatted MD5 hash. Since I am not hashing any other data types than string, I can freely use string as a method parameter (instead of passing a byte array).

The actual class implementation looks like this:

public class MD5HashService : IHash
{
    public string GetHashString(string text)
    {
        if (!string.IsNullOrWhiteSpace(text))
        {
            byte[] buffer = Encoding.UTF8.GetBytes(text);

            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            provider.ComputeHash(buffer);

            string hashed = string.Empty;
            foreach (byte b in provider.Hash)
            {
                hashed += b.ToString("X2");
            }

            return hashed.ToLower();
        }
        else
        {
            return null;
        }
    }
}

NOTE: You must add a reference to System.Security.Cryptography in order to be able to use MD5CryptoServiceProvider.

If you run the WCF service app, you will be able to try it via the WCF Test Client.

Double-click on GetHashString and enter a test value for the text parameter, then click on Invoke. You should get a response that will be the MD5 hashed representation of the source string.

To this point, you have created the service that will handle MD5 hashing. In the existing Windows Phone 7 application solution, add a service reference to the MD5 hashing service:

Now let’s look again at the signature generation algorithm, but from a C# perspective. I created a separate folder in my WP7 application project called Core – here will be the classes that will compose the application engine.

NOTE: I am working with a simple C#-based Windows Phone 7 application – the first and the most basic template is used.

Create a new class inside this folder and call it Authentication – it will contain methods related to user authentication. Set this class as static, since for now there is no need to instantiate it.

Now, the first method will be the one that will build the signature, so here is what my implementation looks like:

public static string Signature { get; set; }

public static void GetSignature(Dictionary<string,string> parameters, string secret)
{
    Signature = null;

    string unHashed = secret;

    int counter = 0;
    string[] parameterNames = new string[parameters.Count];
    string[] parameterValues = new string[parameters.Count];

    foreach(string key in parameters.Keys)
    {
        parameterNames[counter] = key;
        parameterValues[counter] = parameters[key];
        counter++;
    }

    Array.Sort(parameterNames, parameterValues);

    for (int i = 0; i < parameterNames.Length; i++)
    {
        unHashed += parameterNames[i] + parameterValues[i];
    }

    MD5HashService.HashClient hashClient = new MD5HashService.HashClient();
    hashClient.GetHashStringCompleted += new EventHandler<MD5HashService.GetHashStringCompletedEventArgs>(hashClient_GetHashStringCompleted);
    hashClient.GetHashStringAsync(unHashed);
}

static void hashClient_GetHashStringCompleted(object sender, MD5HashService.GetHashStringCompletedEventArgs e)
{
    Signature = e.Result;
}

First of all, you can see that there is a public Signature property – eventually, I will be reading it to see whether a signature was generated or not. The method itself does nothing more than split the dictionary names and values in two arrays, sorts them in alphabetical order, concatenates the strings and then generates the MD5 hash using the WCF service provided, given that the service is running.

NOTE: Any change in parameters or parameter values requires re-signing of the API call.

This is one thing you need to make sure – that the service is running at all times when the application is working. Otherwise, you might encounter problems and you need to handle them appropriately –either provide an alternative way to generate the hash (as I mentioned before, I will be describing this in the final sets of this series) or notify the user that the application cannot currently work due to the unavailability of a dependency service.