Feb 24

I’ve recently written an AIR time tracking application that uses the Harvest & Coopapp APIs. The code and AIR application can be found on the harvestcoop project page on Google Code.

Harvest does provide an iPhone application and also a Harvest Widget for Mac OS X & MS Vista. I decided to create an AIR application so that users on operating systems that don’t have widget support can do their time tracking from the comfort of their own desktops.

The harvestcoop AIR application currently works with Harvest accounts that have widget support.

Feb 10

The Adobe AIR runtime includes a SQLite database so that you can create data driven applications.

The following are the default locations for the SQLite database:

Mac OS X:

/Users/<userName>/Library/Preferences/<applicationName>/Local Store/<databaseFileName>.db

Windows:

C:\Documents and Settings\<userName>\Application Data\<applicationName>\Local Store\<databaseFileName>.db

Adobe AIR 1.5 introduces a feature to encrypt the SQLite database so that you can secure the contents of database. This is could come in handy if you are writing an application that stores information such as customer contact data.

The Open method and the OpenAsync method of the SQLConnection class include an encryptionKey parameter; this parameter tells AIR to encrypt the database file.

The code sample below shows you how to create / open an encrypted SQLite database. Links to an example application & code can be found at the end of this article.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import com.digitaldogbyte.util.Encryption;
 
private var dbConn:SQLConnection;
private var dbFile:File;
private var dbKey:ByteArray;
 
private function init():void
{
	dbKey = Encryption.retrieveKey();
 
	dbFile = File.applicationStorageDirectory.resolvePath("EncryptionExample.db");
	dbFile.createDirectory();
 
	dbConn = new SQLConnection();
	dbConn.addEventListener(SQLEvent.OPEN, handleDbOpen);
	dbConn.addEventListener(SQLErrorEvent.ERROR, handleDbError);
 
	// by passing in the dbKey variable as the encryptionKey parameter we are telling AIR to encrypt the SQLite database
	dbConn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, dbKey);
}

Let’s take a look at the Encryption class to see how the dbKey ByteArray is created. The dbKey value is assigned the return value of the retrieveKey method from the Encryption class. The retrieveKey method checks to see if a key already exists in the application’s EncryptedLocalStore. If the key already exists the retrieveKey method will return the existing key, however if the key does not exist; the generateKey method is called to create a key.

The generateKey method uses the as3crypto library’s Random type to create a key. This key is required to read & write to the encrypted database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.digitaldogbyte.util
{
 
	import com.hurlant.crypto.Crypto;
	import com.hurlant.crypto.prng.Random;
	import com.hurlant.crypto.symmetric.AESKey;
	import com.hurlant.crypto.symmetric.ECBMode;
	import com.hurlant.crypto.symmetric.ICipher;
	import com.hurlant.util.Hex;
 
	import flash.data.EncryptedLocalStore;
	import flash.utils.ByteArray;
 
	public class Encryption
	{
 
		private static var _key:ByteArray;
 
		private static function generateKey():void
		{
			// create key - write to encrypted local store
			_key = new ByteArray();
			var random:Random = new Random();
			random.nextBytes(_key, 16);
			flash.data.EncryptedLocalStore.setItem("key",_key);
		}
 
		public static function retrieveKey():ByteArray
		{
			// try to retrieve key from encrypted local store
			_key = flash.data.EncryptedLocalStore.getItem("key");
			// if no key found in encrypted local store - create a key
			if (_key == null)
			{
				generateKey();
			}
			return _key;
		}
 
	}
}

After you’ve created the encrypted database you can navigate to the database file and try to open it. The database file will not open in your database browser application since the actual database file has been encrypted.

SQLite open error

Here are the download links to the example application & code.

Jan 17

The Adobe AIR 1.1 runtime provides built-in encryption for the local store.

This feature can be used to secure sensitive information like usernames & passwords for web services.

The encrypted local store can be found at these locations on a user’s computer:

Windows: C:\Documents and Settings\<username>\Application Data\Adobe\AIR\ELS\

Mac OS: /Users/<username>/Library/Application Support/Adobe/AIR/ELS/

To use the AIR’s encrypted local store you will need to include the following packages:

1
2
3
import flash.data.EncryptedLocalStore;
 
import flash.utils.ByteArray;

The following code shows an example of encrypting a string and then storing it in the EncryptedLocalStore object. The strToEncrypt string needs to be converted into a ByteArray since the EncryptedLocalStore stores all of it’s data as a hash table that uses strings as keys and byte arrays for the data. In our example, we convert the strToEncrypt into a byteArray as the myByteArray variable using the ByteArray object’s writeUTFBytes method. We are now ready to save our data into the EncryptedLocalStore, which is done by using the EncryptedLocalStore’s setItem method. The setItem method takes a string parameter that it uses as the key for the hash table and then a byte array as the data that it needs to store.

1
2
3
4
5
6
7
var strToEncrypt:String = "Herman";
 
var myByteArray:ByteArray = new ByteArray();
 
myByteArray.writeUTFBytes(strToEncrypt);
 
EncryptedLocalStore.setItem("firstName", myByteArray);

To retrieve the encrypted data from the EncryptedLocaStore you will need to use the getItem method and the string key for the data that you want to retrieve from the hash table.

1
2
3
4
5
6
7
8
var storedValue:ByteArray = EncryptedLocalStore.getItem("firstName");
 
// get the string from the storedValue byte array and store in the strDecrypted variable
var strDecrypted:String = storedValue.readUTFBytes(storedValue.length);
trace(strDecrypted); // "Herman"
 
// read the string from the storedValue byte array
trace(storedValue.readUTFBytes(storedValue.length)); // "Herman"

More documentation can on the EncryptedLocalStore class can be found on Adobe’s site.