zoukankan      html  css  js  c++  java
  • actionscript DES 加密 解密 (AES,其他加密) 拂晓风起

    找了半天其实都没找到什么好的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/

  • 相关阅读:
    winfrom 获取当前系统时间
    netcore3.1API+efcore快速搭建
    php
    php
    php
    php-array的相关函数使用
    php-正则表达式
    vim的复制与粘贴
    vim的多窗口和文件切换操作
    laravel教程中出现500问题
  • 原文地址:https://www.cnblogs.com/kenkofox/p/2144029.html
Copyright © 2011-2022 走看看