Google Authenticator

GoogleAuthenticator

 

As promised a while ago I am going to describe the Google Authenticator today. I do not use my own example source code this time. There is a really nice one here that I will explain. Download the source code and get some extra information from this post. This should be enough know-how to use the Google Authenticator in your own application afterwards.

What is the Google Authenticator?
The Google Authenticator is a program that allows time based passwords. It makes the online identification process much safer. You enter your Id, your password and an extra time based password. A third-party can hardly know the time based password. Even if there is a spy program on your PC that reads all your key inputs, then the hacker only has less than 30 seconds to exploit the opportunity. Otherwise he cannot use your credentials. The time component changes constantly. This is a pretty safe approach.
To steal your identity, the hacker needs to get access to the server database and decrypt your information. This is much more difficult than reading your password by using a key Trojan.

What is TOTP?

Once again our example program is using WPF.
The XAML is pretty much straight forward. Each element (TextBlock or Image) is using Binding to the underlying object. Just the Hmac TextBlock is less intuitive. The text consists of 3 TextBlocks, which in fact look like one. The green text is the second TextBlock. There is no method to write all text into one TextBlock and then color it. This would be far more complex than this 3 TextBlock solution.

 

label


property binding


type


Identity Identity string
Secret Secret string
QR code QRCodeUrl Image
Timestamp Timestamp string
Hmac HmacPart1, HmacPart2, HmacPart3 string
One-time password OneTimePassword string
Seconds to go SecondsToGo string

 

The C# source code has some hyperlinks. You should follow them in case you want to learn some detailed background information. You don’t have to do this. To apply the code in your program it should be enough to study and replicate the example source code. This code is really short and I appreciate this a lot. Many programmers make things far more complicated than needed. Are they trying to show off? I don’t know.

Let’s start from the top now.
The DispatcherTimer is the corresponding class for the good old System.Windows.Forms.Timer class. We are not using WinForms anymore. The idea behind the DispatcherTimer is that the timer fires on the Dispatcher thread. This thread is the same that your window is using. Any other thread could freeze your application.
Do not use the System.Threading.Timer class. This class is neither WPF nor WinForms related. It fires on any thread. You must not access WPF elements on arbitrary threads. On the other hand you should use the System.Threading.Timer class in case you do not want to access WPF. Don’t waste precious time of the Dispatcher thread.

The DispatcherTimer fires each 500 ms (=half second) and assigns the actual value of the 30 second countdown to the property SecondsToGo.

The properties Secret and Identity are initialized with arbitrary example data.
Then the DataContext is set. This enables the data binding between the (XAML) window and the (C#) code.

public MainWindow() {
   InitializeComponent();

   var timer = new DispatcherTimer();
   timer.Interval = TimeSpan.FromMilliseconds(500);
   timer.Tick += (s, e) => SecondsToGo = 30 - Convert.ToInt32(GetUnixTimestamp() % 30);
   timer.IsEnabled = true;

   Secret = new byte[] { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21, 0xDE, 0xAD, 0xBE, 0xEF };
   Identity = "user@host.com";

   DataContext = this;
}

You may have noticed already that the MainWindow class implements the interface INotifyPropertyChanged. This exposes a WPF event called PropertyChanged, which is used to notify clients via binding that a property value has changed.

namespace System.ComponentModel {
  public interface INotifyPropertyChanged {
    // Occurs when a property value changes.
    event PropertyChangedEventHandler PropertyChanged;
  }
}

You notify a client (UI) with the property name (string) rather than a delegate.
The standard WPF pattern looks like this:

public event PropertyChangedEventHandler PropertyChanged;  // INotifyPropertyChanged implementation

protected void OnPropertyChanged(string xPropertyName) {
   PropertyChangedEventHandler h = PropertyChanged;
   if (h == null) return;
   h(this, new PropertyChangedEventArgs(xPropertyName));
} //


private string _MyProperty;
public string  MyProperty { 
  get{ return _MyProperty; } 
  set { _MyProperty = value; OnPropertyChanged(“MyProperty”); } 
} //

And here is the source code from the GoogleAuthenticator example:

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName) {
 if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

private int _secondsToGo;
public int SecondsToGo {
   get { return _secondsToGo; }
   private set { _secondsToGo = value; OnPropertyChanged("SecondsToGo"); if (SecondsToGo == 30) CalculateOneTimePassword(); }
}

You can find that pattern many times in today’s example source code. Be aware that all properties use the same event, which is PropertyChanged. This makes your code look neat, but on the other hand you unfortunately start working with strings instead of delegates. It is part of the MVVM concept to separate code and GUI. For sure it makes debugging much more difficult and code execution slower.

Just to highlight it again. The Hmac consists of three elements. Therefore the property looks like this:

public byte[] Hmac {
  get { return _hmac; }
  private set { _hmac = value; OnPropertyChanged("Hmac"); OnPropertyChanged("HmacPart1"); OnPropertyChanged("HmacPart2"); OnPropertyChanged("HmacPart3"); }
}

What is an Hmac? To make complex interrelations easier, let’s reduce the Hmac description to “a long calculated key”, which is used to determine our time based password. Therefore to generate the key you need some kind of time input. The other component is a static password (=Secret). I added comments in the following code excerpt:

private void CalculateOneTimePassword() {
  // Get the number of seconds since 1/1/1970 and devide them by 30 seconds.
  // Thus one Timestamp unit is 30 seconds.
  Timestamp = Convert.ToInt64(GetUnixTimestamp() / 30);

  // Convert the 64 bit integer Timestamp to a byte array (8 bytes).
  // eg. ba d9 c7 02 00 00 00 00
  // Then reverse them (=> 00 00 00 00 02 c7 d9 ba) and write the result to the byte array "data".
   var data = BitConverter.GetBytes(Timestamp).Reverse().ToArray();

  // Generate the Hmac key from your password (byte array) and time (byte array).
  Hmac = new HMACSHA1(Secret).ComputeHash(data);

  // Bit-operation: Get the last 4 bits of the Hmac. The results are always equal to or between 0 and 15.
  // The offset determines the area of the Hmac that is used to generate the time based password.
  Offset = Hmac.Last() & 0x0F;

  // The Hmac is 20 bytes long. A block of 4 bytes is used for the OneTimePassword, which changes each 30 seconds.
  // 15 is the highest Offset. Therefore the last used byte is number 18 (first byte is zero based).
  // The 19th (=last) byte is the Offset. More precisely the <a href="http://en.wikipedia.org/wiki/Nibble" title="Wiki Nibble Byte" target="_blank">right nibble</a> of the 19th byte is the Offset value.
  // Bit masks are applied on the selected Hmac block to limit the number. The resulting bits are rotated to the left and added together.
  // Basically we are looking at a manual "bit to integer" conversion.
  // the result is then devided by 1,000,000 and only the remainder is taken. Consequently all results are less than 1,000,000.
  // (The bit mask 0xff is useless. I guess it was used to emphasize the technique for readability purposes. 0x7f does make sense.)
  OneTimePassword = (
         ((Hmac[Offset + 0] & 0x7f) << 24) |
         ((Hmac[Offset + 1] & 0xff) << 16) |
         ((Hmac[Offset + 2] & 0xff) << 8) |
         (Hmac[Offset + 3] & 0xff)) % 1000000;
}

When I looked at the program I was trying to find the bitmap for the QR code. You would expect a method somewhere to convert bytes to an image. But this is not the case.
The GetQRCodeUrl method generates a Url. Follow this Url and you will see that it opens an image in your browser. Google does the work for you.
The programmer of that example code has also added the Url to the description on how to generate such QR code Url. Well done! My advice is to have a quick look at it.

private string GetQRCodeUrl() {
  // https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
  var base32Secret = Base32.Encode(Secret);
  return String.Format("https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/{0}%3Fsecret%3D{1}", Identity, base32Secret);
}

Now we have all bits and pieces to use the Google Authenticator. But how?

1) Ask for a user identification and a password. For instance user “super@man.com” and password “Strong5rThan$trong!”.
2) Convert the password to a byte array.
3) Generate the QR code.
4) The user can scan this QR code with his android cell phone. Press “Set up account” followed by “Scan a barcode” in the Google Authenticator app.
5) The new account appears and updates in the Authenticator app. The Identity and Secret were encoded in the QR code. This is why the app knows your name already.
 
Android
 
6) From now on you can ask for the Id, the password and the time based password.
7) Make sure to have a plan B in place. The user might lose access to his Google Authenticator app. You have to provide a new login then.

Btw. I do know some people, who do not lock their tablet PC or cell phone. The Google Authenticator obviously is not for these kind of people. The problem is not behind the screen … it is in front of the screen.

Advertisements

About Bastian M.K. Ohta

Happiness only real when shared.

Posted on May 13, 2014, in Advanced, C#, DataBinding, Programming Patterns, WPF and tagged , , , , , , , , , , , , , , , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: