2009年4月10日 星期五

[flex加密] 應用程序加密1-模擬flash.data.EncryptedLocalStore

在RIA的世界裡,flex和air確實已經起飛了,隨著財富500強企業逐漸採用flex技術實現ria已經各種企業層次的應用開始出現,應用程序和數據安全問題應該逐漸引起flex/air程序員的注意,保密的級別應該和項目的需求緊密相關。例如如果你想開發的是開源的支持廣告的面向大眾的應用程序,為了儘可能多的獲取用戶加密的級別就應該相應的低,同時系統花費在認證用戶上的時間要儘可能的小。另一方面如果你是為企業政府開發內部應用的面板程序,那麼你可能要採用儘量高的加密級別。

在這一系列的三篇關於如何加密Flex應用程序的文章中,我們首先會講述如何在Flex應用程序中採用加密存儲技術加密一個Flex應用程序。在第二篇文章中我們會嘗試使用接口和最小化的加密來對SWC文件進行保護,這個SWC文件正是我們要出售的商業庫。在最後的文章中我們會去瞭解一下NitroLM.com,這是一個商業的API專門從事用戶註冊認證管理,以及企業級的加密技術

在 Adobe最新發佈的AIR1.0版本中,他們提供了向磁盤存儲加密數據的API, flash.data.EncryptedLocalStore類,該類調用WINDOWS DPAI或者是MAC的KEYCHAIN來通過ByteArray數組來存儲數據,很不幸的是,在Flex裡面我們享受不到這項便利,在這一片教程裡面我們會嘗試著模擬這樣的一個類來存儲加密數據

我們要做的第一件事情就是到網絡上去下載一個flex的加密庫方便使用,這裡使用的是Henri創建的AS3Crypto (http://crypto.hurlant.com),我推薦下載源代碼版本,這樣你就可以方便的調試並且能夠瞭解整個加密進程是如何進行的。

在這個例子中(可以查看源代碼)用戶可以在應用程序向WEB SERVICE提請驗證過程中,保存自己的用戶名和密碼,當然這兩個數據的保護不是天衣無縫的,因為數據和隨機生成的KEY是保存在一起的,至於如何將 KEY模糊的放在服務器或者用戶端,還是兩者協商使得KEY的保護更加安全,在此就留作練習了。

FlexEncryptionExample1 example

下面我大概的講述一下代碼:我們有兩個主要的方法,encryptedLoad() 和encryptedSave(). encryptedSave().產生隨機的16位KEY然後使用AES-128算法對我們的用戶名和密碼進行破解,然後將數據保存到BYTE ARRAY




private function encryptedSave():void
{
//創建和獲得共享對象
var so:SharedObject = SharedObject.getLocal("encryptedStore");

//產生隨機的KEY
var key:ByteArray = new ByteArray();
var random:Random = new Random();
random.nextBytes(key, 16);

//將我們的數據加密後保存到ByteArray
var cleartextBytes:ByteArray = new ByteArray();
cleartextBytes.writeUTF(username.text);
cleartextBytes.writeUTF(password.text);

//使用128位AES算法加密
var aes:ICipher = Crypto.getCipher("aes-ecb", key, Crypto.getPad("pkcs5"));
aes.encrypt(cleartextBytes);

//將數據和KEY一起保存
//Note: 注意通常你出於安全考慮你不會這樣做
// 當然前面提到了,這項工作就留作練習了
// security and/or obvuscation.
var dataToStore:ByteArray = new ByteArray();
dataToStore.writeBytes(key);
dataToStore.writeBytes(cleartextBytes);

//將數據保存進共享對象
so.data.ws_creds = dataToStore;
so.flush();

//清空
username.text="";
password.text="";
}

encryptedLoad()讀取我們保存的KEY然後將其加入ByteArray,username和password解密後會被分別解析到各自的域中




private function encryptedLoad():void
{
//從共享對象獲取保存的數據
var so:SharedObject = SharedObject.getLocal("encryptedStore");

var dataToLoad:ByteArray = so.data.ws_creds;

//讀取鍵值
var key:ByteArray = new ByteArray();
dataToLoad.readBytes(key, 0, 16);

//讀取密文
var encryptedBytes:ByteArray = new ByteArray();
dataToLoad.readBytes(encryptedBytes);

//解密
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();
}

【下列文章您可能也有興趣】

沒有留言: