代码改变世界

flash + php对称密钥加密的交互

2013-12-28 18:57  游乐场123  阅读(505)  评论(0编辑  收藏  举报

这几天研究了下php和flash中的对称密钥加密的交互问题,经过研究以后决定,在项目中使用aes加密。问题也就来了,在flash中的加密数据如何与php的amf进行数据交互,最终决定使用base64编码。
一、flash中的aes加密 这里使用的是官方的库as3crypto:一个as3的关于加解密的开源项目 http://code.google.com/p/as3crypto/
加解密类如下:

As3代码 复制代码 收藏代码
  1. package org.randy.crypto   
  2. {  
  3.     import com.hurlant.crypto.symmetric.AESKey;  
  4.     import com.hurlant.crypto.symmetric.ECBMode;  
  5.     import com.hurlant.crypto.symmetric.ICipher;  
  6.     import com.hurlant.crypto.symmetric.IPad;  
  7.     import com.hurlant.crypto.symmetric.PKCS5;  
  8.     import com.hurlant.util.Base64;  
  9.     import com.hurlant.util.Hex;  
  10.     import flash.utils.ByteArray;  
  11.     /**  
  12.      * ...  
  13.      * @author Randy  
  14.      */  
  15.     public class Aes   
  16.     {  
  17.         private var _pad:IPad;//填充方式  
  18.         private var _mode:ICipher;//加密类  
  19.         /**  
  20.          * 构造函数  
  21.          * @param   base64keyString   密钥base64编码字符串  
  22.          */  
  23.         public function Aes(base64keyString:String)   
  24.         {  
  25.             _pad = new PKCS5(); //为了与java保持一致,所以采用PKCS5填充  
  26.             var key:ByteArray = Base64.decodeToByteArray(base64keyString);  
  27.             _mode = new ECBMode(new AESKey(key), _pad);  
  28.             _pad.setBlockSize(_mode.getBlockSize());  
  29.         }  
  30.           
  31.           
  32.         /**  
  33.          * 将明文加密为密文base64编码字符串  
  34.          * @param   plainSrc         明文  
  35.          * @return  密文base64编码  
  36.          */  
  37.         public function encrypt(plainSrc:String):String   
  38.         {  
  39.             var src:ByteArray = Hex.toArray(Hex.fromString(plainSrc));  
  40.             _mode.encrypt(src);  
  41.             return Base64.encodeByteArray(src);  
  42.         }  
  43.  
  44.           
  45.         /**  
  46.          * 将base64编码字符串(密文)解密成 明文  
  47.          * @param   base64Src  密文base64编码字符串  
  48.          * @return  明文  
  49.          */  
  50.         public function decrypt(base64Src:String):String  
  51.         {  
  52.             var src:ByteArray = Base64.decodeToByteArray(base64Src);  
  53.             _mode.decrypt(src);  
  54.             return Base64.decode(Base64.encodeByteArray(src));  
  55.         }  
  56.           
  57.         /**  
  58.          * 释放内存  
  59.          */  
  60.         public function dispose():void  
  61.         {  
  62.             _mode.dispose();  
  63.             _mode = null;  
  64.             _pad = null;  
  65.         }  
  66.     }  
  67.  
package org.randy.crypto 
{
	import com.hurlant.crypto.symmetric.AESKey;
	import com.hurlant.crypto.symmetric.ECBMode;
	import com.hurlant.crypto.symmetric.ICipher;
	import com.hurlant.crypto.symmetric.IPad;
	import com.hurlant.crypto.symmetric.PKCS5;
	import com.hurlant.util.Base64;
	import com.hurlant.util.Hex;
	import flash.utils.ByteArray;
	/**
	 * ...
	 * @author Randy
	 */
	public class Aes 
	{
		private var _pad:IPad;//填充方式
		private var _mode:ICipher;//加密类
		/**
		 * 构造函数
		 * @param	base64keyString   密钥base64编码字符串
		 */
		public function Aes(base64keyString:String) 
		{
			_pad = new PKCS5(); //为了与java保持一致,所以采用PKCS5填充
			var key:ByteArray = Base64.decodeToByteArray(base64keyString);
			_mode = new ECBMode(new AESKey(key), _pad);
			_pad.setBlockSize(_mode.getBlockSize());
		}
		
		
		/**
		 * 将明文加密为密文base64编码字符串
		 * @param	plainSrc		 明文
		 * @return	密文base64编码
		 */
		public function encrypt(plainSrc:String):String 
		{
			var src:ByteArray = Hex.toArray(Hex.fromString(plainSrc));
			_mode.encrypt(src);
			return Base64.encodeByteArray(src);
		}

		
		/**
		 * 将base64编码字符串(密文)解密成 明文
		 * @param	base64Src  密文base64编码字符串
		 * @return	明文
		 */
		public function decrypt(base64Src:String):String
		{
			var src:ByteArray = Base64.decodeToByteArray(base64Src);
			_mode.decrypt(src);
			return Base64.decode(Base64.encodeByteArray(src));
		}
		
		/**
		 * 释放内存
		 */
		public function dispose():void
		{
			_mode.dispose();
			_mode = null;
			_pad = null;
		}
	}

}

测试类:

As3代码 复制代码 收藏代码
  1. package    
  2. {  
  3.     import com.hurlant.util.Base64;  
  4.     import flash.display.Sprite;  
  5.     import org.randy.crypto.Aes;  
  6.     /**  
  7.      * ...  
  8.      * @author Randy  
  9.      */  
  10.     public class AesTest extends Sprite   
  11.     {  
  12.         private var _aes:Aes;  
  13.         public function AesTest()   
  14.         {  
  15.             _aes = new Aes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");  
  16.             trace(_aes.encrypt("hello"));  
  17.             trace(_aes.decrypt(_aes.encrypt("hello")));  
  18.         }     
  19.     }  
package  
{
	import com.hurlant.util.Base64;
	import flash.display.Sprite;
	import org.randy.crypto.Aes;
	/**
	 * ...
	 * @author Randy
	 */
	public class AesTest extends Sprite 
	{
		private var _aes:Aes;
		public function AesTest() 
		{
			_aes = new Aes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");
			trace(_aes.encrypt("hello"));
			trace(_aes.decrypt(_aes.encrypt("hello")));
		}	
	}
}

输出如下: pRkOF9V/Zj5Zca7atjWldA== hello
二、php端
系统win7
由于使用的是EasyPhp5.38,没有带加密扩展,所以需要php4, 解压缩,将php4目录下的php4ts.dll拷贝到c:\windows\System32目录,将extensions目录下的php_mcrypt.dll拷贝至php5的ext目录下,并修改php.ini 加上extension=php_mcrypt.dll, 下载libmcrypt.dll,并拷贝至c:\windows\System32目录,重新启动easyphp
出现警告: PHP Startup:SVWJ: Unable to initialize module Module compiled wit module API=......... 直接忽略掉

Php代码 复制代码 收藏代码
  1. <?php  
  2. class phpAes  
  3. {  
  4.       
  5.     private$td;//加密模块  
  6.     private$key;//密钥  
  7.     private$blocksize;  
  8.       
  9.     publicfunction __construct($base64key)  
  10.     {  
  11.         //密钥  
  12.         $this->key = base64_decode($base64key);  
  13.           
  14.         //打开模块  
  15.         $this->td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', "ecb", '');  
  16.           
  17.         $this->blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'ecb');  
  18.           
  19.         $this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND);  
  20.     }  
  21.       
  22.       
  23.     publicfunction __destruct()  
  24.     {  
  25.         mcrypt_module_close($this->td);  
  26.     }  
  27.       
  28.       
  29.     /**
  30.      * 将明文加密为密文base64编码字符串
  31.      * @param   plainSrc         明文
  32.      * @return  密文base64编码
  33.      */ 
  34.     publicfunction encrypt($plainSrc)  
  35.     {  
  36.         $td = $this->td;  
  37.         //初始化加密  
  38.         mcrypt_generic_init($td, $this->key, $this->iv);  
  39.         //加密  
  40.         $encrypted = mcrypt_generic($td,$this->PaddingPKCS7($plainSrc));  
  41.         //终止加密,主要是一些内存清理  
  42.         mcrypt_generic_deinit($td);  
  43.         //返回  
  44.         returnbase64_encode($encrypted);  
  45.           
  46.     }  
  47.       
  48.     /**
  49.      * 将base64编码字符串(密文)解密成 明文
  50.      * @param   base64Src  密文base64编码字符串
  51.      * @return  明文
  52.      */ 
  53.     publicfunction decrypt($base64Src)  
  54.     {  
  55.         $src = base64_decode($base64Src);  
  56.           
  57.         $td = $this->td;  
  58.         //初始化解密  
  59.         mcrypt_generic_init($td, $this->key, $this->iv);  
  60.         //解密  
  61.         $decrypted = mdecrypt_generic($td,$src);  
  62.         //终止解密,主要是一些内存清理  
  63.         mcrypt_generic_deinit($td);  
  64.         //返回  
  65.         return$this->UnPaddingPKCS7($decrypted);  
  66.     }  
  67.       
  68.     //填充  
  69.     privatefunction PaddingPKCS7 ($data)  
  70.     {  
  71.         $block_size$this->blocksize;  
  72.         $padding_char = $block_size - (strlen($data) % $block_size);  
  73.         $data .= str_repeat(chr($padding_char), $padding_char);  
  74.         return$data;  
  75.     }  
  76.  
  77.     privatefunction UnPaddingPKCS7($text)  
  78.     {  
  79.         $pad = ord($text{strlen($text) - 1});  
  80.         if ($pad > strlen($text)) {  
  81.             return false;  
  82.         }  
  83.         if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {  
  84.             return false;  
  85.         }  
  86.         returnsubstr($text, 0, - 1 * $pad);  
  87.     }  
  88. }  
  89.  
  90. $aes = new phpAes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");  
  91. $enc = $aes->encrypt("hello");  
  92. echo$enc."<br>";  
  93. echo$aes->decrypt($enc);  
  94. ?> 
<?php
class phpAes
{
	
	private $td;//加密模块
	private $key;//密钥
	private $blocksize;
	
	public function __construct($base64key)
	{
		//密钥
		$this->key = base64_decode($base64key);
		
		//打开模块
		$this->td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', "ecb", '');
		
		$this->blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'ecb');
		
		$this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND);
	}
	
	
	public function __destruct()
	{
		mcrypt_module_close($this->td);
	}
	
	
	/**
	 * 将明文加密为密文base64编码字符串
	 * @param	plainSrc		 明文
	 * @return	密文base64编码
	 */
	public function encrypt($plainSrc)
	{
		$td = $this->td;
		//初始化加密
		mcrypt_generic_init($td, $this->key, $this->iv);
		//加密
		$encrypted = mcrypt_generic($td,$this->PaddingPKCS7($plainSrc));
		//终止加密,主要是一些内存清理
		mcrypt_generic_deinit($td);
		//返回
		return base64_encode($encrypted);
		
	}
	
	/**
	 * 将base64编码字符串(密文)解密成 明文
	 * @param	base64Src  密文base64编码字符串
	 * @return	明文
	 */
	public function decrypt($base64Src)
	{
		$src = base64_decode($base64Src);
		
		$td = $this->td;
		//初始化解密
		mcrypt_generic_init($td, $this->key, $this->iv);
		//解密
		$decrypted = mdecrypt_generic($td,$src);
		//终止解密,主要是一些内存清理
		mcrypt_generic_deinit($td);
		//返回
		return $this->UnPaddingPKCS7($decrypted);
	}
	
	//填充
	private function PaddingPKCS7 ($data)
	{
		$block_size =  $this->blocksize;
		$padding_char = $block_size - (strlen($data) % $block_size);
		$data .= str_repeat(chr($padding_char), $padding_char);
		return $data;
	}

	private function UnPaddingPKCS7($text)
	{
		$pad = ord($text{strlen($text) - 1});
		if ($pad > strlen($text)) {
			return false;
		}
		if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
			return false;
		}
		return substr($text, 0, - 1 * $pad);
	}
}

$aes = new phpAes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");
$enc = $aes->encrypt("hello");
echo $enc."<br>";
echo $aes->decrypt($enc);
?>

程序输出 pRkOF9V/Zj5Zca7atjWldA== hello