PageRenderTime 19ms CodeModel.GetById 2ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/flash-src/third-party/com/hurlant/crypto/Crypto.as

http://github.com/gimite/web-socket-js
ActionScript | 287 lines | 193 code | 14 blank | 80 comment | 15 complexity | 30311427d4d84de612558c8c1a12f499 MD5 | raw file
  1/**
  2 * Crypto
  3 * 
  4 * An abstraction layer to instanciate our crypto algorithms
  5 * Copyright (c) 2007 Henri Torgemane
  6 * 
  7 * See LICENSE.txt for full license information.
  8 */
  9package com.hurlant.crypto
 10{
 11	import com.hurlant.crypto.hash.HMAC;
 12	import com.hurlant.crypto.hash.MAC;
 13	import com.hurlant.crypto.hash.IHash;
 14	import com.hurlant.crypto.hash.MD2;
 15	import com.hurlant.crypto.hash.MD5;
 16	import com.hurlant.crypto.hash.SHA1;
 17	import com.hurlant.crypto.hash.SHA224;
 18	import com.hurlant.crypto.hash.SHA256;
 19	import com.hurlant.crypto.prng.ARC4;
 20	import com.hurlant.crypto.rsa.RSAKey;
 21	import com.hurlant.crypto.symmetric.AESKey;
 22	import com.hurlant.crypto.symmetric.BlowFishKey;
 23	import com.hurlant.crypto.symmetric.CBCMode;
 24	import com.hurlant.crypto.symmetric.CFB8Mode;
 25	import com.hurlant.crypto.symmetric.CFBMode;
 26	import com.hurlant.crypto.symmetric.CTRMode;
 27	import com.hurlant.crypto.symmetric.DESKey;
 28	import com.hurlant.crypto.symmetric.ECBMode;
 29	import com.hurlant.crypto.symmetric.ICipher;
 30	import com.hurlant.crypto.symmetric.IMode;
 31	import com.hurlant.crypto.symmetric.IPad;
 32	import com.hurlant.crypto.symmetric.ISymmetricKey;
 33	import com.hurlant.crypto.symmetric.IVMode;
 34	import com.hurlant.crypto.symmetric.NullPad;
 35	import com.hurlant.crypto.symmetric.OFBMode;
 36	import com.hurlant.crypto.symmetric.PKCS5;
 37	import com.hurlant.crypto.symmetric.SimpleIVMode;
 38	import com.hurlant.crypto.symmetric.TripleDESKey;
 39	import com.hurlant.crypto.symmetric.XTeaKey;
 40	import com.hurlant.util.Base64;
 41	
 42	import flash.utils.ByteArray;
 43	
 44	/**
 45	 * A class to make it easy to use the rest of the framework.
 46	 * As a side-effect, using this class will cause most of the framework
 47	 * to be linked into your application, which is not always what you want.
 48	 * 
 49	 * If you want to optimize your download size, don't use this class.
 50	 * (But feel free to read it to get ideas on how to get the algorithm you want.)
 51	 */
 52	public class Crypto
 53	{
 54		private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
 55		
 56		public function Crypto(){
 57		}
 58		
 59		/**
 60		 * Things that should work, among others:
 61		 *  "aes"
 62		 *  "aes-128-ecb"
 63		 *  "aes-128-cbc"
 64		 *  "aes-128-cfb"
 65		 *  "aes-128-cfb8"
 66		 *  "aes-128-ofb"
 67		 *  "aes-192-cfb"
 68		 *  "aes-256-ofb"
 69		 *  "blowfish-cbc"
 70		 *  "des-ecb"
 71		 *  "xtea"
 72		 *  "xtea-ecb"
 73		 *  "xtea-cbc"
 74		 *  "xtea-cfb"
 75		 *  "xtea-cfb8"
 76		 *  "xtea-ofb"
 77		 *  "rc4"
 78		 *  "simple-aes-cbc"
 79		 */
 80		public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
 81			// split name into an array.
 82			var keys:Array = name.split("-");
 83			switch (keys[0]) {
 84				/**
 85				 * "simple" is a special case. It means:
 86				 * "If using an IV mode, prepend the IV to the ciphertext"
 87				 */
 88				case "simple":
 89					keys.shift();
 90					name = keys.join("-");
 91					var cipher:ICipher = getCipher(name, key, pad);
 92					if (cipher is IVMode) {
 93						return new SimpleIVMode(cipher as IVMode);
 94					} else {
 95						return cipher;
 96					}
 97				/**
 98				 * we support both "aes-128" and "aes128"
 99				 * Technically, you could use "aes192-128", but you'd
100				 * only be hurting yourself.
101				 */
102				case "aes":
103				case "aes128":
104				case "aes192":
105				case "aes256":
106					keys.shift();
107					if (key.length*8==keys[0]) {
108						// support for "aes-128-..." and such.
109						keys.shift();
110					}
111					return getMode(keys[0], new AESKey(key), pad);
112				break;
113				case "bf":
114				case "blowfish":
115					keys.shift();
116					return getMode(keys[0], new BlowFishKey(key), pad);
117				/**
118				 * des-ede and des-ede3 are both equivalent to des3.
119				 * the choice between 2tdes and 3tdes is made based
120				 * on the length of the key provided.
121				 */
122				case "des":
123					keys.shift();
124					if (keys[0]!="ede" && keys[0]!="ede3") {
125						return getMode(keys[0], new DESKey(key), pad);
126					}
127					if (keys.length==1) {
128						keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
129					}
130					// fall-through to triple des
131				case "3des":
132				case "des3":
133					keys.shift();
134					return getMode(keys[0], new TripleDESKey(key), pad);
135				case "xtea":
136					keys.shift();
137					return getMode(keys[0], new XTeaKey(key), pad);
138				break;
139				/**
140				 * Technically, you could say "rc4-128" or whatever,
141				 * but really, the length of the key is what counts here.
142				 */
143				case "rc4":
144					keys.shift();
145					return new ARC4(key);
146				break;
147			}
148			return null;
149		}
150		
151		/**
152		 * Returns the size of a key for a given cipher identifier.
153		 */
154		public static function getKeySize(name:String):uint {
155			var keys:Array = name.split("-");
156			switch (keys[0]) {
157				case "simple":
158					keys.shift();
159					return getKeySize(keys.join("-"));
160				case "aes128":
161					return 16;
162				case "aes192":
163					return 24;
164				case "aes256":
165					return 32;
166				case "aes":
167					keys.shift();
168					return parseInt(keys[0])/8;
169				case "bf":
170				case "blowfish":
171					return 16;
172				case "des":
173					keys.shift();
174					switch (keys[0]) {
175						case "ede":
176							return 16;
177						case "ede3":
178							return 24;
179						default:
180							return 8;
181					}
182				case "3des":
183				case "des3":
184					return 24;
185				case "xtea":
186					return 8;
187				case "rc4":
188					if (parseInt(keys[1])>0) {
189						return parseInt(keys[1])/8;
190					}
191					return 16; // why not.
192			}
193			return 0; // unknown;
194		}
195		
196		private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
197			switch (name) {
198				case "ecb":
199					return new ECBMode(alg, padding);
200				case "cfb":
201					return new CFBMode(alg, padding);
202				case "cfb8":
203					return new CFB8Mode(alg, padding);
204				case "ofb":
205					return new OFBMode(alg, padding);
206				case "ctr":
207					return new CTRMode(alg, padding);
208				case "cbc":
209				default:
210					return new CBCMode(alg, padding);
211			}
212		}
213		
214		/**
215		 * Things that should work:
216		 * "md5"
217		 * "sha"
218		 * "sha1"
219		 * "sha224"
220		 * "sha256"
221		 */
222		public static function getHash(name:String):IHash {
223			switch(name) {
224				case "md2":
225					return new MD2;
226				case "md5":
227					return new MD5;
228				case "sha": // let's hope you didn't mean sha-0
229				case "sha1":
230					return new SHA1;
231				case "sha224":
232					return new SHA224;
233				case "sha256":
234					return new SHA256;
235			}
236			return null;
237		}
238		
239		/**
240		 * Things that should work:
241		 * "sha1"
242		 * "md5-64"
243		 * "hmac-md5-96"
244		 * "hmac-sha1-128"
245		 * "hmac-sha256-192"
246		 * etc.
247		 */
248		public static function getHMAC(name:String):HMAC {
249			var keys:Array = name.split("-");
250			if (keys[0]=="hmac") keys.shift();
251			var bits:uint = 0;
252			if (keys.length>1) {
253				bits = parseInt(keys[1]);
254			}
255			return new HMAC(getHash(keys[0]), bits);
256		}
257		
258
259		public static function getMAC(name:String):MAC {
260			
261			var keys:Array = name.split("-");
262			if (keys[0]=="mac") keys.shift();
263			var bits:uint = 0;
264			if (keys.length > 1) {
265				bits = parseInt(keys[1]);
266			}
267			return new MAC(getHash(keys[0]), bits);
268		}
269				
270		
271		public static function getPad(name:String):IPad {
272			switch(name) {
273				case "null":
274					return new NullPad;
275				case "pkcs5":
276				default:
277					return new PKCS5;
278			}
279		}
280		
281		/** mostly useless.
282		 */
283		public static function getRSA(E:String, M:String):RSAKey {
284			return RSAKey.parsePublicKey(M,E);
285		}
286	}
287}