actionscript 3 DES 加解密函数

阅读更多
本同学花了三天时间整理的,网上应该没有别的了,我搜索了一天,没找到,才下定决心自己搞
DesCrypt.as代码
package
{
	import com.hurlant.util.Base64;
	import com.hurlant.util.Hex;
	
	import flash.utils.ByteArray;
	
public class DesCrypt {
	private static const bytebit:Array = [ 128, 64, 32, 16, 8, 4, 2, 1 ];
	private static const bigbyte:Array = [ 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
				0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 ];
		/*
		 * Use the key schedule specified in the Standard (ANSI X3.92-1981).
		 */
	private static const pc1:Array = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
			59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,4, 27, 19, 11, 3 ];
	private static const totrot:Array = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ];
	private static const pc2:Array = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
			51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ];

 public function DesCrypt() {
  //构造
 }
 public function  des(key:String, message:String, encrypt:Boolean, mode:uint, iv:String):ByteArray{
  //declaring this locally speeds things up a bit
  var spfunction1:Array = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
  var spfunction2:Array = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
  var spfunction3:Array = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
  var spfunction4:Array = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
  var spfunction5:Array = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
  var spfunction6:Array = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
  var spfunction7:Array = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
  var spfunction8:Array = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
  //create the 16 or 48 subkeys we will need
  var keys:Array = generateWorkingKey(key);//密钥已经完成
  var m:uint = 0, i:int = 0, j:uint = 0, temp,  right1:int= 0, right2:int= 0, left, right, looping;
  var cbcleft, cbcleft2, cbcright, cbcright2;
  var endloop, loopinc;
//pad the message out with null bytes 填充
//	var messages:ByteArray = Hex.toArray(Hex.fromString(message)); //这玩艺儿还不能随便先换成String去调用函数
//	message = urlencodeGBK(message);
	var messages:ByteArray =new ByteArray; //这玩艺儿还不能随便先换成String去调用函数
//	 messages.writeUTFBytes(message); //这玩艺儿还不能随便先换成String去调用函数
//	 messages = Hex.toArray(Hex.fromString(message)); //这玩艺儿还不能随便先换成String去调用函数
	if(encrypt){
		messages.writeMultiByte(message,"gbk");
		pad(messages);
	}else{
		messages.writeBytes(Base64.decodeToByteArray(message));
	}
//	message = Hex.toString(Hex.fromArray(messages));
  	var len:uint = messages.length; 
	for(var kk:uint = 0; kk < messages.length; kk++){
	}
//  var len:uint = message.length; //这种方法不可取,计算中文长度有问题
//   messages.length = 0;
//  trace("len2:" + messages.length);
  var chunk:uint = 0;
  //set up the loops for single and triple des
  var iterations:uint = keys.length == 32 ? 3 : 9;
  //single or triple des
  if (iterations == 3) {
   looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2);
  } else {
   looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2);
  }

//store the result here
//  var result:String = "";
//  var tempresult:String = "";
  var result:ByteArray = new ByteArray;
  var tempresult:ByteArray = new ByteArray;
  var outOff:uint = 0;
  if (mode == 1) {
   //CBC mode
   cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
   cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
   m = 0;
  }
  //loop through each 64 bit chunk of the message      
  while (m>> 4) ^ right) & 0x0f0f0f0f;
   right ^= temp;
   left ^= (temp << 4);
   temp = ((left >>> 16) ^ right) & 0x0000ffff;
   right ^= temp;
   left ^= (temp << 16);
   temp = ((right >>> 2) ^ left) & 0x33333333;
   left ^= temp;
   right ^= (temp << 2);
   temp = ((right >>> 8) ^ left) & 0x00ff00ff;
   left ^= temp;
   right ^= (temp << 8);
   temp = ((left >>> 1) ^ right) & 0x55555555;
   right ^= temp;
   left ^= (temp << 1);
   left = ((left << 1) | (left >>> 31));
   right = ((right << 1) | (right >>> 31));
   //do this either 1 or 3 times for each chunk of the message
   for (j=0; j>> 4) | (right << 28)) ^ keys[i+1];
     //the result is attained by passing these bytes through the S selection functions
     temp = left;
     left = right;
     right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
    }
    temp = left;
    left = right;
    right = temp;
    //unreverse left and right
   }
   //for either 1 or 3 iterations
   //move then each one bit to the right
   left = ((left >>> 1) | (left << 31));
   right = ((right >>> 1) | (right << 31));
   //now perform IP-1, which is IP in the opposite direction
   temp = ((left >>> 1) ^ right) & 0x55555555;
   right ^= temp;
   left ^= (temp << 1);
   temp = ((right >>> 8) ^ left) & 0x00ff00ff;
   left ^= temp;
   right ^= (temp << 8);
   temp = ((right >>> 2) ^ left) & 0x33333333;
   left ^= temp;
   right ^= (temp << 2);
   temp = ((left >>> 16) ^ right) & 0x0000ffff;
   right ^= temp;
   left ^= (temp << 16);
   temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
   right ^= temp;
   left ^= (temp << 4);
   //for Cipher Block Chaining mode, xor the message with the previous result
   if (mode == 1) {
    if (encrypt) {
     cbcleft = left;
     cbcright = right;
    } else {
     left ^= cbcleft2;
     right ^= cbcright2;
    }
   }
   				
   	tempresult[outOff + 0] = (left >>> 24);
	tempresult[outOff + 1] = ((left >>> 16) & 0xff);
	tempresult[outOff + 2] = ((left >>> 8) & 0xff);
	tempresult[outOff + 3] = (left & 0xff);
	tempresult[outOff + 4] = (right >>> 24);
	tempresult[outOff + 5] = ((right >>> 16) & 0xff);
	tempresult[outOff + 6] = ((right >>> 8) & 0xff);
	tempresult[outOff + 7] = (right & 0xff);
	
	outOff += 8;	
   				
   if (outOff == 512) { 
	    result.writeBytes(tempresult,result.length);
	    tempresult.length = 0;
	    outOff = 0;
   }
  }
	result.writeBytes(tempresult,result.length); 
   
  if(encrypt) { //加密
 	 return result;
  }else{//解密
  
		result.writeBytes(tempresult,result.length)
  		var temary:ByteArray = new ByteArray;
  		temary.writeBytes(result);
  		
  		var templen:uint = temary.length - 1;
  		result.length = 0;
		result.writeBytes(temary,0,(templen - temary[templen] + 1));
	
 	 return result;
  }
  
 }
 		public function generateWorkingKey(keyss:String):Array
		{
			var off:uint = 0;
			var key:ByteArray = Hex.toArray(Hex.fromString(keyss));
			var encrypting:Boolean = true;
			//int[] newKey = new int[32];
			var newKey:Array = [];
			//boolean[] pc1m = new boolean[56], pcr = new boolean[56];
			var pc1m:ByteArray = new ByteArray;
			var pcr:ByteArray = new ByteArray;
			
			var l:uint;
	
			for (var j:uint = 0; j < 56; j++)
			{
				l = pc1[j];
	
				pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
			}
	
			for (var i:uint = 0; i < 16; i++)
			{
				var m:uint;
				var n:uint;
	
				if (encrypting)
				{
					m = i << 1;
				}
				else
				{
					m = (15 - i) << 1;
				}
	
				n = m + 1;
				newKey[m] = newKey[n] = 0;
	
				for (j = 0; j < 28; j++)
				{
					l = j + totrot[i];
					if (l < 28)
					{
						pcr[j] = pc1m[l];
					}
					else
					{
						pcr[j] = pc1m[l - 28];
					}
				}
	
				for (j = 28; j < 56; j++)
				{
					l = j + totrot[i];
					if (l < 56)
					{
						pcr[j] = pc1m[l];
					}
					else
					{
						pcr[j] = pc1m[l - 28];
					}
				}
	
				for (j = 0; j < 24; j++)
				{
					if (pcr[pc2[j]])
					{
						newKey[m] |= bigbyte[j];
					}
	
					if (pcr[pc2[j + 24]])
					{
						newKey[n] |= bigbyte[j];
					}
				}
			}
	
			//
			// store the processed key
			//
			for (i = 0; i != 32; i += 2)
			{
				var i1:uint;
				var i2:uint;
	
				i1 = newKey[i];
				i2 = newKey[i + 1];
	
				newKey[i+1] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
						| ((i2 & 0x00000fc0) >>> 6);
	
				newKey[i] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
						| (i2 & 0x0000003f);
						
						//这里把newKey[i] 和 newKey[i+1]位置对调一下。
			}
			return newKey;
		}
		

		//填充
		public function pad(a:ByteArray):void {
			var c:uint = 8-a.length%8;
			for (var i:uint=0;i0;i--) {
				var v:uint = a[a.length-1];
				a.length--;
				if (c!=v) throw new Error("PKCS#5:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]");
			}
		}
	}
}


mxml调用:
internal var dc:DesCrypt = new DesCrypt;
加密:paras.seqno = Base64.encodeByteArray(dc.des(key,seqNo,true,1,key));
解密:
var resultStrs:ByteArray = dc.des(key,ary[1].密文,false,1,key);
resultStrs.position = 0;
var resultStr:String = resultStrs.readMultiByte(resultStrs.length,"gbk");

能解决中文乱码问题。欢迎一起探讨:http://www.shenfen.info

目前还有一个问题:明文大约50个字符以上的时候能加密,但加密时会出错。欢迎后来者研究一下

你可能感兴趣的:(ActionScript,J#,Flash,UP)