使用as3crypto在Flex中实现AES加密

要在Flex中实现AES加密,可以通过as3crypto实现。但是as3crypto本身的用法比较复杂,一般是封装一下再调用。

下面是9RIA上的一篇文章给出的一个实现,使用中稍感不方便(见注释):

   1: package {
   2: import com.hurlant.crypto.Crypto;
   3: import com.hurlant.crypto.prng.Random;
   4: import com.hurlant.crypto.symmetric.ICipher;
   5: import com.hurlant.crypto.symmetric.IPad;
   6: import com.hurlant.crypto.symmetric.IVMode;
   7: import com.hurlant.crypto.symmetric.PKCS5;
   8: import com.hurlant.util.Base64;
   9: import com.hurlant.util.Hex;
  10:  
  11: import flash.utils.ByteArray;
  12:  
  13: /**
  14: * AES 算法的加密解密工具类。
  15: *
  16: * @author Fuchun
  17: * @langversion 3.0
  18: * @playerversion Flash 11.1
  19: * @productversion 1.0
  20: */
  21: public class AES {
  22:  
  23: /**
  24: * 默认的算法与模式名称。
  25: */
  26: public static const DEFAULT_CIPHER_NAME:String = "aes-128-cbc";
  27:  
  28: /**
  29: * 默认的填充模式。<code>pkcs5</code>
  30: */
  31: public static const DEFAULT_PADNAME:String = "pkcs5";
  32:  
  33: /**
  34: * 无填充。
  35: */
  36: public static const NULL_PADDING:String = "null";
  37:  
  38: private static const RAND:Random = new Random();
  39:  
  40: private var _name:String;
  41: // 密钥
  42: private var _key:ByteArray;
  43: // 向量
  44: private var _iv:ByteArray;
  45: // 填充模式
  46: private var _padName:String;
  47: private var _enc:ICipher;
  48: private var _dec:ICipher;
  49:  
  50: public function AES(key:ByteArray, iv:ByteArray = null, name:String = DEFAULT_CIPHER_NAME, padName:String = DEFAULT_PADNAME) {
  51: _name = name;
  52: _key = key;
  53: _iv = iv;
  54: _padName = padName;
  55: init();
  56: }
  57:  
  58: private function init():void {
  59:   var _pad:IPad = Crypto.getPad(_padName);
  60:   _enc = Crypto.getCipher(_name, _key, _pad);
  61:   _dec = Crypto.getCipher(_name, _key, _pad);
  62:   if (iv) {
  63:     if (_enc is IVMode) {
  64:       var encIvm:IVMode = _enc as IVMode;
  65:       encIvm.IV = iv;
  66:     }
  67:     if (_dec is IVMode) {
  68:       var decIvm:IVMode = _dec as IVMode;
  69:       decIvm.IV = iv;
  70:     }
  71:   }
  72: }
  73:  
  74: public static function generateKey(name:String):ByteArray {
  75:   var keyLength:uint = Crypto.getKeySize(name);
  76:   var key:ByteArray = new ByteArray();
  77:   RAND.nextBytes(key, keyLength);
  78:   return key;
  79: }
  80:  
  81: public static function generateIV(name:String, key:ByteArray):ByteArray {
  82:   var cipher:ICipher = Crypto.getCipher(name, key);
  83:   var iv:ByteArray = new ByteArray();
  84:   RAND.nextBytes(iv, cipher.getBlockSize());
  85:   return iv;
  86: }
  87:  
  88: public function encrypt(input:ByteArray):ByteArray {
  89:   var src:ByteArray = new ByteArray();
  90:   var result:ByteArray = new ByteArray();
  91:   src.writeBytes(input, 0, input.length);
  92:  
  93:   _enc.encrypt(input);
  94:   result.writeBytes(input, 0, input.length);
  95:   input.length = 0;
  96:   input.writeBytes(src, 0, src.length);
  97:  
  98:   src.clear();
  99:   return result;
 100: }
 101:  
 102: public function decrypt(input:ByteArray):ByteArray {
 103:   var src:ByteArray = new ByteArray();
 104:   var result:ByteArray = new ByteArray();
 105:   src.writeBytes(input, 0, input.length);
 106:  
 107:   _dec.decrypt(input);
 108:   result.writeBytes(input, 0, input.length);
 109:   input.length = 0;
 110:   input.writeBytes(src, 0, src.length);
 111:  
 112:   src.clear();
 113:   return result;
 114: }
 115:  
 116: public function encryptString(input:String):ByteArray {
 117:   if (!input || !input.length) {
 118:     return null;
 119:   }
 120:   var inputBytes:ByteArray = new ByteArray();
 121:   inputBytes.writeUTFBytes(input);
 122:   return encrypt(inputBytes);
 123: }
 124:  
 125: //无配对的解密方法,加密后的结果无法直接用decryptString2Hex解密
 126: public function encryptString2Hex(input:String):String {
 127:   var result:ByteArray = encryptString(input);
 128:   return Hex.fromArray(result);
 129: }
 130:  
 131: //无配对的解密方法,加密后的结果无法直接用decryptString2Hex解密
 132: public function encryptString2Base64(input:String):String {
 133:   var result:ByteArray = encryptString(input);
 134:   return Base64.encodeByteArray(result);
 135: }
 136:  
 137: //代码中我们一般习惯直接加密字符串,加密后直接得到密文字符串,这里没有提供这个方法
 138:  
 139: public function decryptString(input:String):ByteArray {
 140:   if (!input || !input.length) {
 141:     return null;
 142:   }
 143:   var inputBytes:ByteArray = new ByteArray();
 144:   inputBytes.writeUTFBytes(input);
 145:   return decrypt(inputBytes);
 146: }
 147:  
 148: public function decryptString2Hex(input:String):String {
 149:   var result:ByteArray = decryptString(input);
 150:   return Hex.fromArray(result);
 151: }
 152:  
 153: public function decryptString2Base64(input:String):String {
 154:   var result:ByteArray = decryptString(input);
 155:   return Base64.encodeByteArray(result);
 156: }
 157:  
 158: public function set iv(value:ByteArray):void {
 159:   _iv = value;
 160: }
 161: public function get iv():ByteArray {
 162:   return _iv;
 163: }
 164: }
 165: }

下面是我修改后的代码:

   1: package utility
   2: {
   3:     import com.hurlant.crypto.Crypto;
   4:     import com.hurlant.crypto.prng.Random;
   5:     import com.hurlant.crypto.symmetric.ICipher;
   6:     import com.hurlant.crypto.symmetric.IPad;
   7:     import com.hurlant.crypto.symmetric.IVMode;
   8:     import com.hurlant.crypto.symmetric.PKCS5;
   9:     import com.hurlant.util.Base64;
  10:     import com.hurlant.util.Hex;
  11:     
  12:     import flash.utils.ByteArray;
  13:     
  14:     /**
  15:      * AES 算法的加密解密工具类。
  16:      *
  17:      * @author Fuchun,modified by caichengyang
  18:      * @langversion 3.0
  19:      * @playerversion Flash 11.1
  20:      * @productversion 1.0
  21:      */
  22:     public class AES {
  23:         
  24:         /**
  25:          * 默认的算法与模式名称。
  26:          */
  27:         public static const DEFAULT_CIPHER_NAME:String = "aes-128-cbc";
  28:         
  29:         /**
  30:          * 默认的填充模式。<code>pkcs5</code>
  31:          */
  32:         public static const DEFAULT_PADNAME:String = "pkcs5";
  33:         
  34:         /**
  35:          * 无填充。
  36:          */
  37:         public static const NULL_PADDING:String = "null";
  38:         
  39:         private static const RAND:Random = new Random();
  40:         
  41:         private var _name:String;
  42:         // 密钥
  43:         private var _key:ByteArray;
  44:         // 向量
  45:         private var _iv:ByteArray;
  46:         // 填充模式
  47:         private var _padName:String;
  48:         private var _enc:ICipher;
  49:         private var _dec:ICipher;
  50:         
  51:         public function AES(key:ByteArray, iv:ByteArray = null, 
  52:                             name:String = DEFAULT_CIPHER_NAME, 
  53:                             padName:String = DEFAULT_PADNAME) {
  54:             _name = name;
  55:             _key = key;
  56:             _iv = iv;
  57:             _padName = padName;
  58:             init();
  59:         }
  60:         
  61:         private function init():void {
  62:             var _pad:IPad = Crypto.getPad(_padName);
  63:             _enc = Crypto.getCipher(_name, _key, _pad);
  64:             _dec = Crypto.getCipher(_name, _key, _pad);
  65:             if (iv) {
  66:                 if (_enc is IVMode) {
  67:                     var encIvm:IVMode = _enc as IVMode;
  68:                     encIvm.IV = iv;
  69:                 }
  70:                 if (_dec is IVMode) {
  71:                     var decIvm:IVMode = _dec as IVMode;
  72:                     decIvm.IV = iv;
  73:                 }
  74:             }
  75:         }
  76:         
  77:         public static function generateKey(name:String):ByteArray {
  78:             var keyLength:uint = Crypto.getKeySize(name);
  79:             var key:ByteArray = new ByteArray();
  80:             RAND.nextBytes(key, keyLength);
  81:             return key;
  82:         }
  83:         
  84:         public static function generateIV(name:String, key:ByteArray):ByteArray {
  85:             var cipher:ICipher = Crypto.getCipher(name, key);
  86:             var iv:ByteArray = new ByteArray();
  87:             RAND.nextBytes(iv, cipher.getBlockSize());
  88:             return iv;
  89:         }
  90:         
  91:         public function set iv(value:ByteArray):void {
  92:             _iv = value;
  93:         }
  94:         
  95:         public function get iv():ByteArray {
  96:             return _iv;
  97:         }
  98:         
  99:         
 100:         // base functions
 101:         public function encrypt(input:ByteArray):ByteArray {
 102:             var src:ByteArray = new ByteArray();
 103:             var result:ByteArray = new ByteArray();
 104:             src.writeBytes(input, 0, input.length);
 105:             
 106:             _enc.encrypt(input);
 107:             result.writeBytes(input, 0, input.length);
 108:             input.length = 0;
 109:             input.writeBytes(src, 0, src.length);
 110:             
 111:             src.clear();
 112:             return result;
 113:         }
 114:         
 115:         public function decrypt(input:ByteArray):ByteArray {
 116:             var src:ByteArray = new ByteArray();
 117:             var result:ByteArray = new ByteArray();
 118:             src.writeBytes(input, 0, input.length);
 119:             
 120:             _dec.decrypt(input);
 121:             result.writeBytes(input, 0, input.length);
 122:             input.length = 0;
 123:             input.writeBytes(src, 0, src.length);
 124:             
 125:             src.clear();
 126:             return result;
 127:         }
 128:         
 129:         
 130:         // encrypt string
 131:         public function encryptString(input:String):ByteArray {
 132:             if (!input || !input.length) {
 133:                 return null;
 134:             }
 135:             var inputBytes:ByteArray = new ByteArray();
 136:             inputBytes.writeUTFBytes(input);
 137:             return encrypt(inputBytes);
 138:         }
 139:         
 140:         public function encryptString2Hex(input:String):String {
 141:             var result:ByteArray = encryptString(input);
 142:             return Hex.fromArray(result);
 143:         }
 144:         
 145:         public function encryptString2Base64(input:String):String {
 146:             var result:ByteArray = encryptString(input);
 147:             return Base64.encodeByteArray(result);
 148:         }
 149:         
 150:         
 151:         // decrypt string
 152:         public function decryptString(input:ByteArray):String {
 153:             var decryptBytes:ByteArray = decrypt(input);
 154:             decryptBytes.position = 0;
 155:             var result:String = decryptBytes.readUTFBytes(decryptBytes.length);
 156:             return result;
 157:         }
 158:         
 159:         public function decryptStringFromHex(input:String):String {
 160:             var inputBytes:ByteArray = Hex.toArray(input);
 161:             var result:String = decryptString(inputBytes);
 162:             return result;
 163:         }
 164:         
 165:         public function decryptStringFromBase64(input:String):String {
 166:             var inputBytes:ByteArray = Base64.decodeToByteArray(input);
 167:             var result:String = decryptString(inputBytes);
 168:             return result;
 169:         }
 170:         
 171:         
 172:     }
 173: }

用法如下:

   1: protected function btnEncrypt_clickHandler(event:MouseEvent):void
   2:             {
   3:                 
   4:                 var key : ByteArray = Hex.toArray("f056180ec970b169980f108c13305642"); //AES.generateKey(AES.DEFAULT_CIPHER_NAME);
   5:                 var iv : ByteArray = Hex.toArray("912467427aa54cccf443d2ae206a63ce"); //AES.generateIV(AES.DEFAULT_CIPHER_NAME, key);
   6:                 
   7:                 lblText.text = lblText.text + "key:" + Hex.fromArray(key) + "\r\n";
   8:                 lblText.text = lblText.text + "iv:" + Hex.fromArray(iv) + "\r\n";
   9:                 
  10:                 var aes : AES = new AES(key, iv, "aes-128-cbc", "null");
  11:                 
  12:                 var plainText:String = "caichengyang";
  13:                 
  14:                 var s1:String = aes.encryptString2Base64(plainText);
  15:                 
  16:                 var s2:String = aes.decryptStringFromBase64(s1);
  17:                 
  18:                 lblText.text = lblText.text + "加密后:" + s1 + "\r\n" + "解密后:" + s2 + "\r\n\r\n";
  19:             }
运行效果如下:
SNAGHTML5cad02

参考:

  1. http://bbs.9ria.com/forum.php?mod=viewthread&tid=160723
  2. http://code.google.com/p/as3crypto/
posted @ 2013-06-20 00:01  Ethan Cai  阅读(3458)  评论(0编辑  收藏  举报