Google Authenticator in HTML5 with WebCrypto

I was poking around the web cryptography API and noticed how powerful it was. It even includes the ability to perform HMAC-SHA1 via the sign method. That is all you need to create TOTP one time passwords. I've done some work in the past on TOTP and knew that it is the backing algorithm for Google's two factor authentication.

Here is the main method that generates the token given the secret, which is base32 encoded. I wrote this in Microsoft's TypeScript, since I think it is great and definitely eased development. For those unfamiliar with Typescript, it is a superset of normal JavaScript so it should be pretty easy to read regardless.
function GenerateToken(base32EncodedSecret: string, callback: (number) => void): void {
    if (!msCrypto) {
        throw "MsCrypto not found";
    }

    // Google by default puts spaces in the secret, so strip them out.
    base32EncodedSecret = base32EncodedSecret.replace(/\s/g, "");

    // This method decodes the secret to bytes, the code is excluded here.
    var keyData: Uint8Array = GoogleAuthenticator.Base32Decode(base32EncodedSecret);
    var time: number = Math.floor(Date.now() / 30000);
    var data: Uint8Array = GoogleAuthenticator.NumericToUint8Array(time);

    // We need to create a key that the subtle object can actualy do work with
    var importKeyOp: KeyOperation = msCrypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-1" }, false, ["sign"]);

    importKeyOp.onerror = function (e) {
        console.log("error event handler fired.");
        callback(-1);
    }

    importKeyOp.oncomplete = function (e) {
        var key: Key = e.target.result;
        // HMAC the secret with the time
        var signkey = msCrypto.subtle.sign({ name: "HMAC", hash: "SHA-1" }, key, data);

        signkey.onerror = function (evt) {
            console.error("onerror event handler fired.");
            callback(-1);
        };

        signkey.oncomplete = function (evt) {
            // Now that we have the hash, we need to perform the HOTP specific byte selection
            // (called dynamic truncation in the RFC)
            var signature: ArrayBuffer = evt.target.result;

            if (signature) {
                var signatureArray: Uint8Array = new Uint8Array(signature);
                var offset: number = signatureArray[signatureArray.length - 1] & 0xf;
                var binary: number = ((signatureArray[offset] & 0x7f) << 24) |
                    ((signatureArray[offset + 1] & 0xff) << 16) |
                    ((signatureArray[offset + 2] & 0xff) << 8) |
                    (signatureArray[offset + 3] & 0xff);
                callback(binary % 1000000);

            } else {
                console.error("Sign with HMAC - SHA-1: FAIL");
                callback(-1);
            }
        };
    };
}

Setup Process


Token


For those of you who are worried about how this changes the multi-factor part of multi-factor auth, you should worry not. The demo page below saves the secret in the localStorage, which is device specific. So having the secret is an indicator that you have the device. This satisfies the "something you have" factor of multi-factor authentication. Currently only Internet Explorer 11 supports some form of the msCrypto object so if you want to check out the demo, you'll need to download that.

Demo page

Where is it 5 o'clock?

In 2003 Alan Jackson and Jimmy Buffett released the song It's Five O'clock Somewhere. It went on to spend 8 weeks at number one on the Billboard Hot Country Songs. It also reached number 17 on the US Hot 100, making it a huge crossover hit.

This poses the question, where is it 5 o'clock exactly at this moment and what is going on in that area? My brother created a website http://wheresitfiveoclock.com based off of publically available material to determine where in the world it is 5 o'clock by using time zones and day light savings calculations. Sources include:
  1. http://en.wikipedia.org/wiki
  2. http://www.timeanddate.com/
  3. http://www.worldweatheronline.com/
  4. http://www.yelp.com/
I decided to create a windows phone application based off of the website http://wheresitfiveoclock.com/. This app shows you where it is currently 5 o'clock with the weather information. Hopefully, this app leads you to travel more and see more of the world. Leisure is important to your health so say it with us: It's 5 o'clock somewhere.
Main view

Live tile support

DAAP Media Player for Windows 8

DAAP, the digital audio access protocol that is commonly used by NAS devices to deliver personal music shares to your devices, is now available in Windows 8 Store! Now you can stream your music while using all of your Windows applications. The current release is available in German, English, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, and Simplified and Traditional Chinese.
Please leave any concerns or issues in the comments below.
Initial setup process.
List of albums.
Playing a song.

Coalescable Timers in Typescript

Not too many people may be familiar with the concept of coalescable timers, but they an be very useful for a power conscious application without hard real time requirements. Coalesce literally means "to grow together". In the case of timers, this means that multiple timers are allowed to be combined into one. This is usually done to reduce the number of times a computer is woken from a low power state to perform some action. This can be incredibly useful with mobile processors where power is very critical. As more and more applications move towards web applications to reduce re-implementing code in multiple mobile SDKs, it becomes necessary to introduce an implementation of coalescable timers into JavaScript, the client side logic language of modern web applications.

The idea is that when creating a timer, a tolerance value is specified that states how much variability is allowed in the timer. The tolerance allows timers with similar values to "grow together" into one timer. Examine the following example:

Timer 1: Trigger every 1 minutes with tolerance of 10 seconds
Timer 2: Trigger every 50 seconds with tolerance of 10 seconds

Coalesced Timer: Trigger every 60 seconds

Now becomes time to describe an algorithm for implementing coalescable timers. The goal is to minimize the number of times a timer is triggered. When a new timer is created, examine the existing timers, if any of the existing coalesced timers satisfy the requirements, add the new timer to the existing ones. If no existing coalesced timer handles the requirements specified, then create a new coalesced timer. Below is an implementation in TypeScript, which compiles down to basic JavaScript:

// Module containing all logic for coalescable timers
module Coalescable {
    // Variable holding all coalesced timers that are aggregating the individual timers
    var timers: CoalescedTimer[] = new CoalescedTimer[];

    export function SetCoalescableTimeout(expression: any, msec: number, tolerance: number): void {
        // Search existing coalesced timers for timers that can accomodate this request
        for (var index: number = 0; index < timers.length; index++) {
            var coalescedTimer: CoalescedTimer = timers[index];
            if (msec - tolerance < coalescedTimer.msec &&
                msec + tolerance > coalescedTimer.msec) {
                coalescedTimer.Timers.push(expression);
                return;
            }
        }

        // Create a new coalesced timer since none can accomodate this request
        var coalescedTimer: CoalescedTimer = new CoalescedTimer(msec)
        coalescedTimer.Timers.push(expression);
        timers.push(coalescedTimer);
    }

    class CoalescedTimer {
        constructor(public msec: number) {
            setInterval(function () => {
                for (var index: number = 0; index < this.Timers.length; index++) {
                    new Function(this.Timers[index])();
                }
            }, msec);
        }

        public Timers: any[] = new any[];
    }
}

Coalescable.SetCoalescableTimeout("alert('1')", 5000, 10); // Will create a new coalesced timer since none exist.
Coalescable.SetCoalescableTimeout("alert('2')", 6000, 2000); // Will be coalesced into the existing timer to run every 5000ms.


Obviously this is a first implementation. Many improvements could be made, such as minimizing distance from threshold when more than one coalesced timer exists to service a new timer request. There are also a few other interesting scenarios. Say creating a new timer means that a new coalesced timer will be created. In this case, it may make sense to move an existing timer to this new coalesced timer to reduce the difference from the requested interval and the coalesced interval. Also, cancelling or clearing a timeout should be supported.

DAAP Media Player released on Windows Phone!

Today marks the general availability of the first version of DAAP Media Player for Windows Phone! As some of you may know, DAAP, digital audio access protocol, is a protocol initially developed by Apple for sharing audio across computers through iTunes. A while ago, my brother and I released an Android implementation of the DAAP protocol, but now is the time for Windows Phone. As with all platforms, it pays to have the implementation be a native application that takes full advantage of the platforms features.

We have taken the opportunity to do some optimizations that we have been wanting to do to the Android application but did not do initially. First and foremost, songs are cached in a local database after initially being fetched. This is opposite to Android where all songs are downloaded every time the application is launched. This can be a major benefit for libraries with a large amount of songs. Also, the Windows Phone platform has a great mechanism for playing songs independently of the application. This means that you can do any other tasks while listening to your music with no interruptions. You can change songs, play/pause, etc. from the volume button just as if DAAP Media Player was your local media application (even from the lock screen!).




The pricing is roughly $2 with a trial ad-supported version supported. You can find the application in the store by searching DAAP or installing from the Windows Phone Store website: DAAP Media Player.

HOTP on Windows Phone 8!

Recently I have been working on porting the existing Android one time password application to Windows Phone 8. Well the efforts have come to fruition. Now you can use your Windows Phone Device to create HOTP tokens for your authentication purposes. Below are some teaser screenshots:

Let me know any comments on the application below. You can download the application from the Windows Store here: http://www.windowsphone.com/en-us/store/app/hotp/ad7aad9e-294f-4731-9a5f-994a9cbaed13

Emulating Windows 8 Tilt Effect

When you click on a tile from the start screen on Windows 8, there is a nice effect where the tile "tilts" backwards towards the pointer or touch location. See below for an example:

Taken from IEBlog
The tilt direction appears be to based on the mouse or touch location. The image above was taken when the click was towards the right side of the live tile. The regions of the image that dictate the direction of the tilt is dictated roughly by the below guidelines:

Regions that determine direction of tilt.

The center region simply causes the tile to be depressed as an HTML button or other similar icon. The first step towards emulating this behavior is to determine the direction of the tilt. Once the direction is chose, we must apply the correct CSS3 3D transform to the tile.

Let's first define our points of interest relative to our object, which will be defined by its top-left coordinate (left, top) with width width and height height.
1. Center defined by rectangle:
(left+(width/2)-(.1*left), top+(height/2)-(.1*top)) width .2*width height .2*height.
2. Descending line defined by point (left, top) and slope (-height / width):
ytop = (-height / width) * (x - left)
3. Ascending line defined by point (left, top+height) and slope (heigh,width):
y - (top + height) = (height / width) * (x - left)

Now that we've defined our points of interest, we can take the incoming click and determine which direction the tilt is. The below code will install an event handler for the mouse down event for ever element with class "tilt".
        $(".tilt").each(function () {
            $(this).mousedown(function (event) {
                // Does the click reside in the center of the object 
                if (event.pageX > $(this).offset().left + ($(this).outerWidth() / 2) - (0.1 * $(this).outerWidth()) &&
                        event.pageX < $(this).offset().left + ($(this).outerWidth() / 2) + (0.1 * $(this).outerWidth()) &&
                        event.pageY > $(this).offset().top + ($(this).outerHeight() / 2) - (0.1 * $(this).outerHeight()) &&
                        event.pageY < $(this).offset().top + ($(this).outerHeight() / 2) + (0.1 * $(this).outerHeight())) {
                    $(this).css("transform", "perspective(500px) translateZ(-15px)");
                } else {
                    var slope = $(this).outerHeight() / $(this).outerWidth(),
                        descendingY = (slope * (event.pageX - $(this).offset().left)) + $(this).offset().top,
                        ascendingY = (-slope * (event.pageX - $(this).offset().left)) + $(this).offset().top + $(this).outerHeight();

                    if (event.pageY < descendingY) {
                        if (event.pageY < ascendingY) {
                            // top region
                            $(this).css("transform", "perspective(500px) rotateX(8deg)");
                        } else {
                            // right region
                            $(this).css("transform", "perspective(500px) rotateY(8deg)");
                        }
                    } else {
                        if (event.pageY > ascendingY) {
                            // bottom region
                            $(this).css("transform", "perspective(500px) rotateX(-8deg)");
                        } else {
                            // left region
                            $(this).css("transform", "perspective(500px) rotateY(-8deg)");
                        }
                    }
                }
            });

            $(this).mouseup(function (event) {
                $(this).css("transform", "");
            });
        });

Here is a below working example. Click the image to see the tilt effect:


Let me know if you find any particular issues with any browsers or have any comments below. I also should plug the useful tools used to help with this code: