这几天研究了下php和flash中的对称密钥加密的交互问题,经过研究以后决定,在项目中使用aes加密。问题也就来了,在flash中的加密数据如何与php的amf进行数据交互,最终决定使用base64编码。
一、flash中的aes加密 这里使用的是官方的库as3crypto:一个as3的关于加解密的开源项目 http://code.google.com/p/as3crypto/
加解密类如下:
- 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;
- }
- }
- }
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; } } }
测试类:
- 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")));
- }
- }
- }
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:windowsSystem32目录,将extensions目录下的php_mcrypt.dll拷贝至php5的ext目录下,并修改php.ini 加上extension=php_mcrypt.dll, 下载libmcrypt.dll,并拷贝至c:windowsSystem32目录,重新启动easyphp
出现警告: PHP Startup:SVWJ: Unable to initialize module Module compiled wit module API=......... 直接忽略掉
- <?php
- class phpAes
- {
- private$td;//加密模块
- private$key;//密钥
- private$blocksize;
- publicfunction __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);
- }
- publicfunction __destruct()
- {
- mcrypt_module_close($this->td);
- }
- /**
- * 将明文加密为密文base64编码字符串
- * @param plainSrc 明文
- * @return 密文base64编码
- */
- publicfunction encrypt($plainSrc)
- {
- $td = $this->td;
- //初始化加密
- mcrypt_generic_init($td, $this->key, $this->iv);
- //加密
- $encrypted = mcrypt_generic($td,$this->PaddingPKCS7($plainSrc));
- //终止加密,主要是一些内存清理
- mcrypt_generic_deinit($td);
- //返回
- returnbase64_encode($encrypted);
- }
- /**
- * 将base64编码字符串(密文)解密成 明文
- * @param base64Src 密文base64编码字符串
- * @return 明文
- */
- publicfunction 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);
- }
- //填充
- privatefunction PaddingPKCS7 ($data)
- {
- $block_size = $this->blocksize;
- $padding_char = $block_size - (strlen($data) % $block_size);
- $data .= str_repeat(chr($padding_char), $padding_char);
- return$data;
- }
- privatefunction 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;
- }
- returnsubstr($text, 0, - 1 * $pad);
- }
- }
- $aes = new phpAes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");
- $enc = $aes->encrypt("hello");
- echo$enc."<br>";
- echo$aes->decrypt($enc);
- ?>
<?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