找了半天其实都没找到什么好的DES加密代码。
难怪有一个博主说,他找了半天没找到自己实现了一个。http://www.iteye.com/topic/422575
但貌似他自己都说加密大的明文会出错,所以我就不敢试用了。
另外,在天地会下载了一个,发现功能还是能达到的,貌似是把js版转过来的。但是加密的速度非常的低,应该是实现的问题。比我在一个外国佬微博找到的AES加密代码还要慢十几倍。
(!!!补充,最后发现还是外国佬写好的那个Crypto库( http://code.google.com/p/as3crypto/ )最好,虽然用起来很麻烦。见文章最后。)
不过,无论怎么说,都值得称赞,在这里分享一下代码。
package crypto { import flash.display.Sprite; import flash.events.EventDispatcher; import flash.events.ProgressEvent; import flash.utils.ByteArray; /** * Des加密 * * @author 闪闪小巴依 */ public class DES { //IP变换,用于打乱64位明文 private const IP:Array = [ 58,50,42,34,26,18,10,2, 60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6, 64,56,48,40,32,24,16,8, 57,49,41,33,25,17,9,1, 59,51,43,35,27,19,11,3, 61,53,45,37,29,21,13,5, 63,55,47,39,31,23,15,7 ]; //IP-1变换,用户输出64位密文 private const IP_1:Array = [ 40,8,48,16,56,24,64,32, 39,7,47,15,55,23,63,31, 38,6,46,14,54,22,62,30, 37,5,45,13,53,21,61,29, 36,4,44,12,52,20,60,28, 35,3,43,11,51,19,59,27, 34,2,42,10,50,18,58,26, 33,1,41,9,49,17,57,25 ]; //PC_1变换 private const PC_1:Array = [ 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4 ]; //PC_2变换 private const PC_2:Array = [ 14,17,11,24,1,5,3, 28,15,6,21,10,23,19, 12,4,26,8,16,7,27, 20,13,2,41,52,31, 37,47,55,30,40,51,45, 33,48,44,49,39,56,34, 53,46,42,50,36,29,32 ]; //E变换,将32位膨胀为48位 private const E:Array = [ 32,1,2,3,4,5, 4,5,6,7,8,9, 8,9,10,11,12,13, 12,13,14,15,16,17, 16,17,18,19,20,21, 20,21,22,23,24,25, 24,25,26,27,28,29, 28,29,30,31,32,1 ]; //P变换,将膨胀后的压缩回32位 private static var P:Array = [ 16,7,20,21, 29,12,28,17, 1,15,23,26, 5,18,31,10, 2,8,24,14, 32,27,3,9, 19,13,30,6, 22,11,4,25 ]; private const sbox:Array = [ [ [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 ], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13] ], [ [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9] ], [ [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ] ], [ [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 ], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14] ], [ [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 ], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 ], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3] ], [ [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 ] ], [ [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 ], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 ], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 ] ], [ [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 ], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11] ] ]; public const leftMoveStep:Array = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]; private var key:ByteArray; private var key_i:Array; public function DES(key:ByteArray) { this.key = key; if(this.key.length != 8){ throw new Error("key 错误"); }else{ var keyArray:Array = new Array(); for(var i:int = 0;i<8;i++){ var ts:Array = this.D2B(this.key[i]); for(var j:int = 0;j<8;j++){ keyArray.push(ts[j]); } } //trace(keyArray); this.key_i = this.getKeys(keyArray); for(var m:int = 0;m<key_i.length;m++){ //trace("key"+m+":"+key_i[m]); } //trace(this.key_i) //trace(this.key_i); } } public function encrypt(source:ByteArray):ByteArray{ var ret:ByteArray = new ByteArray(); var filledSource:ByteArray = this.fullFill64(source); var a:Number = filledSource.length/8; var b:Number = filledSource.length%8; for(var i:int = 0;i<a;i++){ var block:Array = new Array(); for(var m:int = 0;m<8;m++){ var bytes:Array = this.D2B(filledSource[i*8+m]); for(var n:int = 0;n<8;n++){ block.push(bytes[n]); } } var encryptedBlock:Array = this.encryptUnit(block); for(var k:int = 0;k<8;k++){ var encryptedByte:Array = new Array(); for(var l:int = 0;l<8;l++){ encryptedByte.push(encryptedBlock[k*8+l]); } var encryptedInt:int = this.B2D(encryptedByte); ret.writeByte(encryptedInt); } } return ret; } public function decrypt(source:ByteArray):ByteArray{ var ret:ByteArray = new ByteArray(); var a:Number = source.length/8; var b:Number = source.length%8; for(var i:int = 0;i<a;i++){ var block:Array = new Array(); for(var m:int = 0;m<8;m++){ var bytes:Array = this.D2B(source[i*8+m]); for(var n:int = 0;n<8;n++){ block.push(bytes[n]); } } var decryptedBlock:Array = this.decriptUnit(block); for(var k:int = 0;k<8;k++){ var decryptedByte:Array = new Array(); for(var l:int = 0;l<8;l++){ decryptedByte.push(decryptedBlock[k*8+l]); } var decryptedInt:int = this.B2D(decryptedByte); ret.writeByte(decryptedInt); } } ret = this.filterFilled(ret); return ret; } private function encryptUnit(source:Array):Array{ var ret:Array ; var IPRes:Array = this.IPConvort(source); //trace("IPRes"+IPRes); for(var i:int = 0;i<16;i++){ this.f(IPRes,i,1); //trace("the"+i+"loop"); //trace(IPRes); } ret = this.IP_1Convert(IPRes); return ret; } private function decriptUnit(source:Array):Array{ var ret:Array; var IPRes:Array = this.IPConvort(source); for(var i:int = 15;i>=0;i--){ this.f(IPRes,i,0); } ret = this.IP_1Convert(IPRes); return ret; } public function IPConvort(source:Array):Array{ var ret:Array = new Array(64); for(var i:int = 0;i<ret.length;i++){ ret[i] = source[IP[i]-1]; } return ret; } public function IP_1Convert(source:Array):Array{ var ret:Array = new Array(64); for(var i:int = 0;i<64;i++){ ret[i] = source[IP_1[i]-1]; } return ret; } public function PC_1Convert(source:Array):Array{ var ret:Array = new Array(56); for(var i:int = 0;i<56;i++){ ret[i] = source[PC_1[i]-1]; } return ret; } public function B2D(source:Array):int{ var ret:int = 0; for(var i:int =0;i<source.length;i++){ ret += source[source.length-1-i]*Math.pow(2,i); } return ret; } public function D2B(source:int):Array{ var ret:Array = new Array(); var m:int = source; var ts:int = 0; var n:int = 0; do{ ts = m; m = Math.floor(m/2); n= ts - m*2; ret.push(n); }while(m != 0); for(m = ret.length;m<8;m++){ ret.push(0); } m = Math.floor(ret.length/2); for(n = 0;n<m;n++){ ts = ret[n]; ret[n] = ret[ret.length-1-n]; ret[ret.length -1-n] = ts; } return ret; } public function getKeys(source:Array):Array{ var ret:Array = new Array(); var keyByte:Array = PC_1Convert(source); for(var i:int = 0;i<16;i++){ leftMove(keyByte,leftMoveStep[i]); var keyI:Array = new Array(48) for(var j:int = 0;j<48;j++){ keyI[j] = keyByte[PC_2[j]-1]; } ret.push(keyI); } return ret; } public function leftMove(source:Array,offset:int):void{ var ret:Array = new Array(56); var c0:Array = new Array(28); var d0:Array = new Array(28); var c1:Array = new Array(28); var d1:Array = new Array(28); for(var i:int = 0;i<28;i++){ c0[i] = source[i]; d0[i] = source[i+28]; } if(offset == 1){ for(var i:int = 0;i<27;i++){ c1[i] = c0[i+1]; d1[i] = d0[i+1]; } c1[27] = c0[0]; d1[27] = d0[0]; }else if(offset == 2){ for(var i:int = 0;i<26;i++){ c1[i] = c0[i+2]; d1[i] = d0[i+2]; } c1[26] = c0[0]; d1[26] = d0[0]; c1[27] = c0[1]; d1[27] = d0[1]; } for(var i:int = 0;i<28;i++){ source[i] = c1[i]; source[i+28] = d1[i]; } } private function fullFill64(byte:ByteArray):ByteArray{ var ret:ByteArray = new ByteArray(); var len:int = byte.length; var padlen:int = 8 - (len%8); var newlen:int = len+padlen; ret.length = newlen; ret.writeBytes(byte,0,byte.length); for(var i:int = len;i<newlen;i++){ ret.writeByte(padlen); } return ret; } private function filterFilled(byte:ByteArray):ByteArray{ var ret:ByteArray = new ByteArray(); var padlen:int = byte[byte.length-1]; var len:int = byte.length - padlen; ret.length = len; ret.writeBytes(byte,0,len); return ret; } private function f(source:Array,times:int,flag:int):void{ var l0:Array = new Array(32); var r0:Array = new Array(32); var l1:Array = new Array(32); var r1:Array = new Array(32); var re:Array = new Array(48); var s:Array = new Array(8); for(var i:int = 0;i<8;i++){ s[i] = new Array(6); } var sout:Array = new Array(32); var rp:Array = new Array(32); for(var i:int = 0;i<32;i++){ l0[i] = source[i]; r0[i] = source[i+32]; } //trace("l0"+l0); //trace("r0"+r0); for(var i:int = 0;i<48;i++){ re[i] = r0[E[i]-1]; re[i] = re[i]+this.key_i[times][i]; if(re[i] == 2){ re[i] = 0; } } //var outS:String = "====================\n"; for(var i:int = 0;i<8;i++){ for(var j:int = 0;j<6;j++){ s[i][j] = re[i*6+j]; //outS += s[i][j]; //outS += ","; } //outS +="\n"; var x:int = s[i][1]*8+s[i][2]*4+s[i][3]*2+s[i][4]*1; var y:int = s[i][0]*2+s[i][5]*1; var sboxData:int = this.sbox[i][y][x]; //trace("s"+i+": "+sboxData); var outB:Array = this.D2B(sboxData); for(var j:int = 0;j<4;j++){ sout[i*4+j] = outB[4+j]; } } //outS += "=================="; //trace(outS); for(var i:int = 0;i<32;i++){ rp[i] = sout[P[i]-1]; l1[i] = r0[i]; r1[i] = l0[i]; r1[i] = l0[i]+rp[i]; if(r1[i] == 2){ r1[i] = 0; } if(((flag==0)&&(times == 0))||((flag==1)&&(times==15))){ source[i] = r1[i]; source[i+32] = l1[i]; }else{ source[i] = l1[i]; source[i+32] = r1[i]; } } } } }
另外,关于AES的加密,可以看http://code.google.com/p/as3crypto/
写了一个DES的封装(因为我只用了DES):大家只需要下载了Crypto库,加入到项目即可使用下边这个类。加密速度很好,180bytes的中文字,只需要300多毫秒加密解密(2.8G双核CPU)
package crypto { import com.hurlant.crypto.Crypto; import com.hurlant.crypto.symmetric.AESKey; import com.hurlant.util.Hex; import flash.utils.ByteArray; public class Crypto { private var key:ByteArray = Hex.toArray("abababababababab"); //8 bytes hex num public function Crypto() { } public function encryptByDES(plainText:ByteArray):ByteArray { var copy:ByteArray = copyArray(plainText); Crypto.getCipher("des-ecb", key).encrypt(copy); return copy; } public function decryptByDES(encryptedText:ByteArray):ByteArray { var copy:ByteArray = copyArray(encryptedText); Crypto.getCipher("des-ecb", key).decrypt(copy); return copy; } private function copyArray(origin:ByteArray):ByteArray{ var copyArray:ByteArray = new ByteArray; var pos:int = origin.position; origin.position = 0; copyArray.writeBytes(origin, 0, origin.length); origin.position = pos; return copyArray; } } }
或者http://code.google.com/p/lostinactionscript/