no commit message
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* Crypto
|
||||
*
|
||||
* An abstraction layer to instanciate our crypto algorithms
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto
|
||||
{
|
||||
import com.hurlant.crypto.hash.HMAC;
|
||||
import com.hurlant.crypto.hash.IHash;
|
||||
import com.hurlant.crypto.hash.MD2;
|
||||
import com.hurlant.crypto.hash.MD5;
|
||||
import com.hurlant.crypto.hash.SHA1;
|
||||
import com.hurlant.crypto.hash.SHA224;
|
||||
import com.hurlant.crypto.hash.SHA256;
|
||||
import com.hurlant.crypto.prng.ARC4;
|
||||
import com.hurlant.crypto.rsa.RSAKey;
|
||||
import com.hurlant.crypto.symmetric.AESKey;
|
||||
import com.hurlant.crypto.symmetric.BlowFishKey;
|
||||
import com.hurlant.crypto.symmetric.CBCMode;
|
||||
import com.hurlant.crypto.symmetric.CFB8Mode;
|
||||
import com.hurlant.crypto.symmetric.CFBMode;
|
||||
import com.hurlant.crypto.symmetric.CTRMode;
|
||||
import com.hurlant.crypto.symmetric.DESKey;
|
||||
import com.hurlant.crypto.symmetric.ECBMode;
|
||||
import com.hurlant.crypto.symmetric.ICipher;
|
||||
import com.hurlant.crypto.symmetric.IMode;
|
||||
import com.hurlant.crypto.symmetric.IPad;
|
||||
import com.hurlant.crypto.symmetric.ISymmetricKey;
|
||||
import com.hurlant.crypto.symmetric.IVMode;
|
||||
import com.hurlant.crypto.symmetric.NullPad;
|
||||
import com.hurlant.crypto.symmetric.OFBMode;
|
||||
import com.hurlant.crypto.symmetric.PKCS5;
|
||||
import com.hurlant.crypto.symmetric.SimpleIVMode;
|
||||
import com.hurlant.crypto.symmetric.TripleDESKey;
|
||||
import com.hurlant.crypto.symmetric.XTeaKey;
|
||||
import com.hurlant.util.Base64;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* A class to make it easy to use the rest of the framework.
|
||||
* As a side-effect, using this class will cause most of the framework
|
||||
* to be linked into your application, which is not always what you want.
|
||||
*
|
||||
* If you want to optimize your download size, don't use this class.
|
||||
* (But feel free to read it to get ideas on how to get the algorithm you want.)
|
||||
*/
|
||||
public class Crypto
|
||||
{
|
||||
private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
|
||||
|
||||
public function Crypto(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work, among others:
|
||||
* "aes"
|
||||
* "aes-128-ecb"
|
||||
* "aes-128-cbc"
|
||||
* "aes-128-cfb"
|
||||
* "aes-128-cfb8"
|
||||
* "aes-128-ofb"
|
||||
* "aes-192-cfb"
|
||||
* "aes-256-ofb"
|
||||
* "blowfish-cbc"
|
||||
* "des-ecb"
|
||||
* "xtea"
|
||||
* "xtea-ecb"
|
||||
* "xtea-cbc"
|
||||
* "xtea-cfb"
|
||||
* "xtea-cfb8"
|
||||
* "xtea-ofb"
|
||||
* "rc4"
|
||||
* "simple-aes-cbc"
|
||||
*/
|
||||
public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
|
||||
// split name into an array.
|
||||
var keys:Array = name.split("-");
|
||||
switch (keys[0]) {
|
||||
/**
|
||||
* "simple" is a special case. It means:
|
||||
* "If using an IV mode, prepend the IV to the ciphertext"
|
||||
*/
|
||||
case "simple":
|
||||
keys.shift();
|
||||
name = keys.join("-");
|
||||
var cipher:ICipher = getCipher(name, key, pad);
|
||||
if (cipher is IVMode) {
|
||||
return new SimpleIVMode(cipher as IVMode);
|
||||
} else {
|
||||
return cipher;
|
||||
}
|
||||
/**
|
||||
* we support both "aes-128" and "aes128"
|
||||
* Technically, you could use "aes192-128", but you'd
|
||||
* only be hurting yourself.
|
||||
*/
|
||||
case "aes":
|
||||
case "aes128":
|
||||
case "aes192":
|
||||
case "aes256":
|
||||
keys.shift();
|
||||
if (key.length*8==keys[0]) {
|
||||
// support for "aes-128-..." and such.
|
||||
keys.shift();
|
||||
}
|
||||
return getMode(keys[0], new AESKey(key), pad);
|
||||
break;
|
||||
case "bf":
|
||||
case "blowfish":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new BlowFishKey(key), pad);
|
||||
/**
|
||||
* des-ede and des-ede3 are both equivalent to des3.
|
||||
* the choice between 2tdes and 3tdes is made based
|
||||
* on the length of the key provided.
|
||||
*/
|
||||
case "des":
|
||||
keys.shift();
|
||||
if (keys[0]!="ede" && keys[0]!="ede3") {
|
||||
return getMode(keys[0], new DESKey(key), pad);
|
||||
}
|
||||
if (keys.length==1) {
|
||||
keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
|
||||
}
|
||||
// fall-through to triple des
|
||||
case "3des":
|
||||
case "des3":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new TripleDESKey(key), pad);
|
||||
case "xtea":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new XTeaKey(key), pad);
|
||||
break;
|
||||
/**
|
||||
* Technically, you could say "rc4-128" or whatever,
|
||||
* but really, the length of the key is what counts here.
|
||||
*/
|
||||
case "rc4":
|
||||
keys.shift();
|
||||
return new ARC4(key);
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a key for a given cipher identifier.
|
||||
*/
|
||||
public static function getKeySize(name:String):uint {
|
||||
var keys:Array = name.split("-");
|
||||
switch (keys[0]) {
|
||||
case "simple":
|
||||
keys.shift();
|
||||
return getKeySize(keys.join("-"));
|
||||
case "aes128":
|
||||
return 16;
|
||||
case "aes192":
|
||||
return 24;
|
||||
case "aes256":
|
||||
return 32;
|
||||
case "aes":
|
||||
keys.shift();
|
||||
return parseInt(keys[0])/8;
|
||||
case "bf":
|
||||
case "blowfish":
|
||||
return 16;
|
||||
case "des":
|
||||
keys.shift();
|
||||
switch (keys[0]) {
|
||||
case "ede":
|
||||
return 16;
|
||||
case "ede3":
|
||||
return 24;
|
||||
default:
|
||||
return 8;
|
||||
}
|
||||
case "3des":
|
||||
case "des3":
|
||||
return 24;
|
||||
case "xtea":
|
||||
return 8;
|
||||
case "rc4":
|
||||
if (parseInt(keys[1])>0) {
|
||||
return parseInt(keys[1])/8;
|
||||
}
|
||||
return 16; // why not.
|
||||
}
|
||||
return 0; // unknown;
|
||||
}
|
||||
|
||||
private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
|
||||
switch (name) {
|
||||
case "ecb":
|
||||
return new ECBMode(alg, padding);
|
||||
case "cfb":
|
||||
return new CFBMode(alg, padding);
|
||||
case "cfb8":
|
||||
return new CFB8Mode(alg, padding);
|
||||
case "ofb":
|
||||
return new OFBMode(alg, padding);
|
||||
case "ctr":
|
||||
return new CTRMode(alg, padding);
|
||||
case "cbc":
|
||||
default:
|
||||
return new CBCMode(alg, padding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work:
|
||||
* "md5"
|
||||
* "sha"
|
||||
* "sha1"
|
||||
* "sha224"
|
||||
* "sha256"
|
||||
*/
|
||||
public static function getHash(name:String):IHash {
|
||||
switch(name) {
|
||||
case "md2":
|
||||
return new MD2;
|
||||
case "md5":
|
||||
return new MD5;
|
||||
case "sha": // let's hope you didn't mean sha-0
|
||||
case "sha1":
|
||||
return new SHA1;
|
||||
case "sha224":
|
||||
return new SHA224;
|
||||
case "sha256":
|
||||
return new SHA256;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work:
|
||||
* "sha1"
|
||||
* "md5-64"
|
||||
* "hmac-md5-96"
|
||||
* "hmac-sha1-128"
|
||||
* "hmac-sha256-192"
|
||||
* etc.
|
||||
*/
|
||||
public static function getHMAC(name:String):HMAC {
|
||||
var keys:Array = name.split("-");
|
||||
if (keys[0]=="hmac") keys.shift();
|
||||
var bits:uint = 0;
|
||||
if (keys.length>1) {
|
||||
bits = parseInt(keys[1]);
|
||||
}
|
||||
return new HMAC(getHash(keys[0]), bits);
|
||||
}
|
||||
|
||||
public static function getPad(name:String):IPad {
|
||||
switch(name) {
|
||||
case "null":
|
||||
return new NullPad;
|
||||
case "pkcs5":
|
||||
default:
|
||||
return new PKCS5;
|
||||
}
|
||||
}
|
||||
|
||||
/** mostly useless.
|
||||
*/
|
||||
public static function getRSA(E:String, M:String):RSAKey {
|
||||
return RSAKey.parsePublicKey(M,E);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user