Home >
In the RIA world, Flex and AIR applications have really taken off. With that has come increased adoption by Fortune 500 companies and new enterprise-level apps taking advantage of the Adobe Flash platform. Application and data security should always be a concern of the Flex/AIR developer. The level of paranoia the developer should implement must be weighed against the goals of the project. For example, if you’re developing an open source or advertising-supported application intended for a wide public audience, you probably want to implement fairly minimal security measures in order to reach the widest audience and limit the amount of time you spend managing users in the system. On the other hand, if you’re being contracted to write a dashboard application for a large company or government for internal use, you’d probably want to implement security measures at the high-end of the spectrum.
In this series of three articles on the topic of Encryption in Flex Applications, we’ll first cover a basic data encryption and storage example in a Flex application. In article two, we’ll look at using an interface and doing some minimal encryption on a SWC file to protect an example commercial library we want to sell. In the final installment, we’ll take a look at using some of the features of NitroLM.com which is a commercial API for user registration, management, and entire application encryption.
In Adobe’s newly-released version of AIR 1.0, they provide an API for storing encrypted data to the hard drive. The flash.data.EncryptedLocalStore class uses the Windows DPAPI or KeyChain on MacOS to store and retrieve encrypted data as a ByteArray. Unfortunately, this capability isn’t available to us in a Flex application. In this example, I’ll demonstrate creating similar functionality by encrypting data stored in a local SharedObject.
The first thing we need is to download an encryption library to use in our Flex application. I’m using AS3Crypto (http://crypto.hurlant.com) created by Henri Torgemane. I recommend downloading the source code so you can debug easier and see how the encryption is working.
In this example (view-source enabled), the user can save a username and password between runs of the application to be used by a web service. It’s not totally secure since the randomly generated key is stored along with the encrypted data. I’ll leave it as an exercise for the reader to come up with clever ways to obfuscate the key or use alternative server-side repositories that are more secure.
FlexEncryptionExample1 example
Let’s walk through the code. We have two main methods, encryptedLoad() and encryptedSave(). encryptedSave() generates a random 16 byte key, and runs the AES-128 encryption algorithm on our username and password that we’ve packaged into a ByteArray.
private function encryptedSave():void
{
//create or retrieve the current shared object
var so:SharedObject = SharedObject.getLocal("encryptedStore");
//generate a random key
var key:ByteArray = new ByteArray();
var random:Random = new Random();
random.nextBytes(key, 16);
//store our data to encrypt into a ByteArray
var cleartextBytes:ByteArray = new ByteArray();
cleartextBytes.writeUTF(username.text);
cleartextBytes.writeUTF(password.text);
//encrypt using 128b AES encryption using a random key
var aes:ICipher = Crypto.getCipher("aes-ecb", key, Crypto.getPad("pkcs5"));
aes.encrypt(cleartextBytes);
//store key along with the data to decrypt
//Note: normally you'd never do this for security reasons,
// but I'll leave it to the reader to handle additional
// security and/or obvuscation.
var dataToStore:ByteArray = new ByteArray();
dataToStore.writeBytes(key);
dataToStore.writeBytes(cleartextBytes);
//save the blob of encrypted stuff in the SharedObject
so.data.ws_creds = dataToStore;
so.flush();
//clear out the fields
username.text="";
password.text="";
}
encryptedLoad() reads in our key and uses it to decrypt the rest of the ByteArray. The values are then loaded into their respective form fields from the decrypted ByteArray.
private function encryptedLoad():void
{
//create or retrieve the current shared object
var so:SharedObject = SharedObject.getLocal("encryptedStore");
var dataToLoad:ByteArray = so.data.ws_creds;
//read in our key
var key:ByteArray = new ByteArray();
dataToLoad.readBytes(key, 0, 16);
//read in our encryptedText
var encryptedBytes:ByteArray = new ByteArray();
dataToLoad.readBytes(encryptedBytes);
//decrypt using 128b AES encryption
var aes:ICipher = Crypto.getCipher("aes-ecb", key, Crypto.getPad("pkcs5"));
aes.decrypt(encryptedBytes);
encryptedBytes.position = 0;
username.text = encryptedBytes.readUTF();
password.text = encryptedBytes.readUTF();
}
Hopefully with this example, you can start to see some of the possibilities for encrypting your data using Adobe Flex/AIR.




Facebook Application Development
With all the decompilers out there, I guess this would be usefull only to encrypted SWF as well right? (Since AIR apps can be decompiled as well)
(Wow the captcha was hard)
That's correct. Since it can be decompiled to figure out where the key lives you'd either have to encrypt the swf, or store the key in a location secured by another mechanism. I'll get into SWC and SWF encryption in the 2 follow-on articles.
tanks
encryptedLoad() reads in our key and uses it to decrypt the rest of the ByteArray. The values are then loaded into their respective form fields from the decrypted ByteArray.
why?
@demm The purpose of this article was to simulate (not duplicate) the functionality of encryptedLocalStore. For simplicity, the decryption key was stored alongside the encrypted payload. The values are loaded into the form fields just so that you can verify that the decryption worked.
Thanks for the example, but do you perhaps have an example that shows how to encrypt/decrypt a serialized AMF object?
I want too example how to encrypt AMF objects
@Essay, Normally, you don't need to worry about encrypting AMF since it's used to send over a network connection. Just make sure the receiving server is using https and you should be fine security-wise.