4 * An abstraction layer to instanciate our crypto algorithms
\r
5 * Copyright (c) 2007 Henri Torgemane
\r
7 * See LICENSE.txt for full license information.
\r
9 package com.hurlant.crypto
\r
11 import com.hurlant.crypto.hash.HMAC;
\r
12 import com.hurlant.crypto.hash.MAC;
\r
13 import com.hurlant.crypto.hash.IHash;
\r
14 import com.hurlant.crypto.hash.MD2;
\r
15 import com.hurlant.crypto.hash.MD5;
\r
16 import com.hurlant.crypto.hash.SHA1;
\r
17 import com.hurlant.crypto.hash.SHA224;
\r
18 import com.hurlant.crypto.hash.SHA256;
\r
19 import com.hurlant.crypto.prng.ARC4;
\r
20 import com.hurlant.crypto.rsa.RSAKey;
\r
21 import com.hurlant.crypto.symmetric.AESKey;
\r
22 import com.hurlant.crypto.symmetric.BlowFishKey;
\r
23 import com.hurlant.crypto.symmetric.CBCMode;
\r
24 import com.hurlant.crypto.symmetric.CFB8Mode;
\r
25 import com.hurlant.crypto.symmetric.CFBMode;
\r
26 import com.hurlant.crypto.symmetric.CTRMode;
\r
27 import com.hurlant.crypto.symmetric.DESKey;
\r
28 import com.hurlant.crypto.symmetric.ECBMode;
\r
29 import com.hurlant.crypto.symmetric.ICipher;
\r
30 import com.hurlant.crypto.symmetric.IMode;
\r
31 import com.hurlant.crypto.symmetric.IPad;
\r
32 import com.hurlant.crypto.symmetric.ISymmetricKey;
\r
33 import com.hurlant.crypto.symmetric.IVMode;
\r
34 import com.hurlant.crypto.symmetric.NullPad;
\r
35 import com.hurlant.crypto.symmetric.OFBMode;
\r
36 import com.hurlant.crypto.symmetric.PKCS5;
\r
37 import com.hurlant.crypto.symmetric.SimpleIVMode;
\r
38 import com.hurlant.crypto.symmetric.TripleDESKey;
\r
39 import com.hurlant.crypto.symmetric.XTeaKey;
\r
40 import com.hurlant.util.Base64;
\r
42 import flash.utils.ByteArray;
\r
45 * A class to make it easy to use the rest of the framework.
\r
46 * As a side-effect, using this class will cause most of the framework
\r
47 * to be linked into your application, which is not always what you want.
\r
49 * If you want to optimize your download size, don't use this class.
\r
50 * (But feel free to read it to get ideas on how to get the algorithm you want.)
\r
54 private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
\r
56 public function Crypto(){
\r
60 * Things that should work, among others:
\r
80 public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
\r
81 // split name into an array.
\r
82 var keys:Array = name.split("-");
\r
85 * "simple" is a special case. It means:
\r
86 * "If using an IV mode, prepend the IV to the ciphertext"
\r
90 name = keys.join("-");
\r
91 var cipher:ICipher = getCipher(name, key, pad);
\r
92 if (cipher is IVMode) {
\r
93 return new SimpleIVMode(cipher as IVMode);
\r
98 * we support both "aes-128" and "aes128"
\r
99 * Technically, you could use "aes192-128", but you'd
\r
100 * only be hurting yourself.
\r
107 if (key.length*8==keys[0]) {
\r
108 // support for "aes-128-..." and such.
\r
111 return getMode(keys[0], new AESKey(key), pad);
\r
116 return getMode(keys[0], new BlowFishKey(key), pad);
\r
118 * des-ede and des-ede3 are both equivalent to des3.
\r
119 * the choice between 2tdes and 3tdes is made based
\r
120 * on the length of the key provided.
\r
124 if (keys[0]!="ede" && keys[0]!="ede3") {
\r
125 return getMode(keys[0], new DESKey(key), pad);
\r
127 if (keys.length==1) {
\r
128 keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
\r
130 // fall-through to triple des
\r
134 return getMode(keys[0], new TripleDESKey(key), pad);
\r
137 return getMode(keys[0], new XTeaKey(key), pad);
\r
140 * Technically, you could say "rc4-128" or whatever,
\r
141 * but really, the length of the key is what counts here.
\r
145 return new ARC4(key);
\r
152 * Returns the size of a key for a given cipher identifier.
\r
154 public static function getKeySize(name:String):uint {
\r
155 var keys:Array = name.split("-");
\r
159 return getKeySize(keys.join("-"));
\r
168 return parseInt(keys[0])/8;
\r
188 if (parseInt(keys[1])>0) {
\r
189 return parseInt(keys[1])/8;
\r
191 return 16; // why not.
\r
193 return 0; // unknown;
\r
196 private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
\r
199 return new ECBMode(alg, padding);
\r
201 return new CFBMode(alg, padding);
\r
203 return new CFB8Mode(alg, padding);
\r
205 return new OFBMode(alg, padding);
\r
207 return new CTRMode(alg, padding);
\r
210 return new CBCMode(alg, padding);
\r
215 * Things that should work:
\r
222 public static function getHash(name:String):IHash {
\r
228 case "sha": // let's hope you didn't mean sha-0
\r
240 * Things that should work:
\r
245 * "hmac-sha256-192"
\r
248 public static function getHMAC(name:String):HMAC {
\r
249 var keys:Array = name.split("-");
\r
250 if (keys[0]=="hmac") keys.shift();
\r
252 if (keys.length>1) {
\r
253 bits = parseInt(keys[1]);
\r
255 return new HMAC(getHash(keys[0]), bits);
\r
259 public static function getMAC(name:String):MAC {
\r
261 var keys:Array = name.split("-");
\r
262 if (keys[0]=="mac") keys.shift();
\r
264 if (keys.length > 1) {
\r
265 bits = parseInt(keys[1]);
\r
267 return new MAC(getHash(keys[0]), bits);
\r
271 public static function getPad(name:String):IPad {
\r
274 return new NullPad;
\r
281 /** mostly useless.
\r
283 public static function getRSA(E:String, M:String):RSAKey {
\r
284 return RSAKey.parsePublicKey(M,E);
\r