Encrypted Local Store in AIR

One of the questions I encountered regularly during the AIR Bus Tour was about encryption using AIR. There’s an obvious sensitivity towards having an application remember certain details (like passwords) about the user, and then storing that data in the clear in a text file. During AIR Beta 1, I suggested that folks use one of the various ActionScript encryption libraries. I’m happy to report that AIR Beta 2 includes an “encrypted local store” for developers to use.

The class EncryptedLocalStore, as one might imagine, is what’s used to gain access to this functionality. It has only a few methods on it, and all of them are static. If you want to put something in the store, you call EncryptedLocalStore.setItem(). To get something out of the store you call EncryptedLocalStore.getItem(). And to remove something entirely from the store, you call EncryptedLocalStore.removeItem(). Pretty sensible, right? Let’s take a closer look at the details.

I should note that as per the documentation, each application has it’s own encrypted local store, and that store can only be accessed from the “application” security sandbox. AIR uses DPAPI on Windows and KeyChain on Mac OS. Data is encrypted to the local store using AES-CBC 128-bit. Also a warning that this feature is still changing a little and data stored using AIR Beta 2 may not be retrievable using later versions. This will stabilize for AIR 1.0.

Everything put in the store, and retrieved from the store, as a ByteArray, which I found a little confusing at first. To better clarify how to use this, I took the common case of remembering a user’s login information. There are two parts to my approach. The first part is in storing the information. This means getting the information out of the input field, writing it to a ByteArray, and then putting the data in the encrypted store.

function doSignIn()
{
	var data = null;
	var email = null;
	var password = null;	

	if( document.getElementById( 'remember' ).checked )
	{
		email = document.getElementById( 'email' ).value;
		password = document.getElementById( 'password' ).value;			

		data = new air.ByteArray();
		data.writeUTFBytes( email );
		air.EncryptedLocalStore.setItem( 'email', data );

		data = new air.ByteArray();
		data.writeUTFBytes( password );
		air.EncryptedLocalStore.setItem( 'password', data );
	} else {
		removeUser();
	}

	document.getElementById( 'login' ).style.visibility = 'hidden';
}

When calling EncryptedLocalStore.setItem(), you need to have the data already in a ByteArray. When storing a String, this can be most easily accomplished by creating a new ByteArray instance, and then using ByteArray.writeUTFBytes(), which takes a String argument. The other part of EncryptedLocalStore.setItem() that is important is the name of the item you’re setting. This acts as a label for reference later when you want to get, change, or remove the data, so don’t forget it.

The “UTF” part is important in both reading and writing string data, so don’t try and shortcut it to ByteArray.writeMultiBytes().

When you choose to store the users login credentials is really up to you. You might choose to store the data when they hit the “Remember me” button. You might choose to store the data when they hit the “Sign In” button. Or you might even wait to store the data, until a successful login has been made. Your call, of course, but I generally like to wait for a successful login, that way I’m storing data that will actually help the user in the future.

Next up comes getting the data back out of the encrypted local store. In the case of “Remember me” functionality, this will most commonly be done when the AIR application starts. You get the data using the item name you used to store it. And as you might expect, the ByteArray.readUTFBytes() will get the String back out of the ByteArray.

function rememberUser()
{
	var email = air.EncryptedLocalStore.getItem( 'email' );
	var pass = air.EncryptedLocalStore.getItem( 'password' );

	if( email != null )
	{
		document.getElementById( 'email' ).value = email.readUTFBytes( email.bytesAvailable );
		document.getElementById( 'password' ).value = pass.readUTFBytes( pass.bytesAvailable );
		document.getElementById( 'remember' ).checked = true;
	} else {
		document.getElementById( 'email' ).value = '';
		document.getElementById( 'password' ).value = '';
		document.getElementById( 'remember' ).checked = false;
	}
}

It occurred to me that I could take the email address and password, and concatenate them with a comma (or the likes). Then I’d only have to store one piece of data. Geting it back out would still only be one call too, but then I’d have to String.split() the data back apart. In the end, I decided to simply store each piece of data separately in case I ever needed just the one value.

Finally comes the task of removing the data in the situation that the user no longer wants you to store it. The API makes that task easy enough by calling EncryptedLocalStore.removeItem() and specifying the name of item it is you want to remove.

function removeUser()
{
	air.EncryptedLocalStore.removeItem( 'email' );
	air.EncryptedLocalStore.removeItem( 'password' );
}

The harder part is deciding when to actually remove the data. Do you clear the values right when the user turns of the “Remember me”? Maybe you check the button, and then remove the values when the application closes? I chose to remove the information as soon as the button was clicked, but I’d be interested in hearing your thoughts on the matter, so drop me a comment. Example code is attached to this post, and includes one very ugly and rudimentary login screen.

4 Responses to “Encrypted Local Store in AIR”

  1. Phil Molaro Says:

    How does this apply to the SQLite database? I would like to encrypt mine in my AIR app. I assume I could encrypt the db file and decode it, but wouldn’t that be a performance hit?

    Also, on a slightly related note, I haven’t looked into it yet but I was wondering if the Yahoo SimpleDB will play well or at all with AIR. SQLite is ok, but I have been synching data to and from an Oracle DB and there are some data types I would like it to support better.

    Thanks again for coming to Raleigh on the AIR Bus Tour!

  2. Mark Says:

    The login screen it wasn’t that ugly. Mine are even uglier.:)

  3. arama motoru Says:

    The login screen it wasn’t that ugly. Mine are even uglier.:)
    thanks

  4. Simon G. Says:

    wow, thanks man for share this actually i was looking for this…

    Simon G.

Leave a Reply

You must be logged in to post a comment.


order cialis in canada clomid without prescription lasix for sale synthroid prescription discount cialis overnight delivery buy generic propecia order no rx viagra buy viagra low price buy viagra online viagra sale cheapest viagra buy cialis from india buy cheap acomplia online buy clomid cheap purchase clomid order discount viagra online where to buy viagra price of lasix price of propecia soma without prescription purchase clomid online find viagra no prescription required buy generic zithromax synthroid online stores price of synthroid purchase lasix cialis approved cheapest generic viagra online find viagra cialis pharmacy online best price viagra buy cheapest cialis on line cheapest viagra price buying cialis lasix generic order cheap cialis find viagra online buy cialis lowest price best price for viagra purchase zithromax lowest price soma cheapest generic cialis order cialis online cialis free delivery lowest price viagra purchase viagra no rx order cheap cialis online viagra australia discount clomid cheap synthroid tablets cheap cialis pharmacy online zithromax online synthroid buy viagra on internet levitra prescription viagra tablets sale cialis cialis price buy cheap clomid online cheap viagra in canada buy clomid online buy generic viagra cheap viagra from canada cialis in bangkok discount viagra online cialis australia acomplia for sale buy cialis no rx buy levitra without prescription viagra online stores buy cheap viagra online viagra cheapest price viagra rx