php代码实现aes加密

发现php4的加密模块在php5的不被支持了,硬要加上这个模块会导致启动时候出现警告对话框。
于是花了一天时间将as3的加密类翻译成了php的,该加密类是google的开源项目
[url]http://code.google.com/p/as3crypto/[/url]


<?php
require_once("PKCS5.php");
require_once("AESKey.php");
require_once("ECBMode.php");
require_once("Hex.php");

class Aes
{
private $_pad;//填充方式
private $_mode;//加密类
/**
* 构造函数
* @param base64keyString 密钥base64编码字符串
*/
public function Aes($base64keyString)
{
$this->_pad = new PKCS5(); //为了与java保持一致,所以采用PKCS5填充
$key = Hex::string2ByteArray(base64_decode($base64keyString));
$this->_mode = new ECBMode(new AESKey($key), $this->_pad);
$this->_pad->setBlockSize($this->_mode->getBlockSize());
}


/**
* 将明文加密为密文base64编码字符串
* @param plainSrc 明文
* @return 密文base64编码
*/
public function encrypt($plainSrc)
{
$src = Hex::string2ByteArray($plainSrc);
$src = $this->_mode->encrypt($src);

return base64_encode(Hex::ByteArray2String($src));
}


/**
* 将base64编码字符串(密文)解密成 明文
* @param base64Src 密文base64编码字符串
* @return 明文
*/
public function decrypt($base64Src)
{
$src = base64_decode($base64Src);
$src = $this->_mode->decrypt(Hex::string2ByteArray($src));
return Hex::byteArray2String($src);
}

/**
* 释放内存
*/
public function dispose()
{
$this->_mode->dispose();
}
}
//var_dump(Hex::string2ByteArray(base64_decode("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=")));

$_aes = new Aes("MK2X82eL6jkKbzvlJU1ZMR6rcKO+SBhmbPOmFD/2Mxw=");
//echo "=================<br>";
$ret = $_aes->encrypt("1234567890abcdef1234567890abcdefaaafdsfsdffasfasfasfasdf");
echo $ret;
var_dump($_aes->decrypt($ret));

?>



<?php
require_once("IPad.php");

class PKCS5 implements IPad
{
private $blockSize = 0;

public function PKCS5($blockSize=0) {
$this->blockSize = $blockSize;
}

public function pad($a)
{
$c = $this->blockSize-count($a)%$this->blockSize;
for ($i=0;$i<$c;++$i){
$a[] = $c;
}
return $a;
}
public function unpad($a)
{
$len = count($a);
$c = $len % $this->blockSize;
if ($c!=0) throw new Exception("PKCS#5::unpad: ByteArray.length isn't a multiple of the blockSize");
$c = $a[$len-1];
array_splice($a,$len-$c,$c);
return $a;
}

public function setBlockSize($bs)
{
$this->blockSize = $bs;
}
}
?>




<?php
require_once("ISymmetricKey.php");
require_once("AESKeyInclude.php");
require_once("Hex.php");


class AESKey implements ISymmetricKey
{

private $_keyByte;
private $_keyLength;
private $_nNr;
private $_stateByte;
private $_tempByte;

public function AESKey($key/*:ByteArray*/) {
$this->_tempByte = array();
$this->_stateByte = array();
$this->_keyLength = count($key);
$this->_keyByte = $key;
$this->expandKey();
}

// produce Nb bytes for each round
private function expandKey()
{
$tmp0=0;
$tmp1=0;
$tmp2=0;
$tmp3=0;
$tmp4=0;
$idx=0;
$Nk = $this->_keyLength/4;
//echo("count:".$Nk."<br>".count($this->_keyByte)."<br>");
$this->_nNr = $Nk+6;
$_keyByte = $this->_keyByte;
$_nNr = $this->_nNr;
$Nb = AESKeyInclude::$Nb;
$Sbox = AESKeyInclude::$_Sbox;
$Rcon = AESKeyInclude::$_Rcon;

for( $idx = $Nk; $idx < $Nb * ($_nNr + 1); $idx++ ) {
$tmp0 = $_keyByte[4*$idx - 4];
$tmp1 = $_keyByte[4*$idx - 3];
$tmp2 = $_keyByte[4*$idx - 2];
$tmp3 = $_keyByte[4*$idx - 1];
if( !($idx % $Nk) ) {
$tmp4 = $tmp3;
$tmp3 = $Sbox[$tmp0];
$tmp0 = $Sbox[$tmp1] ^ $Rcon[$idx/$Nk];
$tmp1 = $Sbox[$tmp2];
$tmp2 = $Sbox[$tmp4];
} else if( $Nk > 6 && $idx % $Nk == 4 ) {
$tmp0 = $Sbox[$tmp0];
$tmp1 = $Sbox[$tmp1];
$tmp2 = $Sbox[$tmp2];
$tmp3 = $Sbox[$tmp3];
}

$_keyByte[4*$idx+0] = $_keyByte[4*$idx - 4*$Nk + 0] ^ $tmp0;
$_keyByte[4*$idx+1] = $_keyByte[4*$idx - 4*$Nk + 1] ^ $tmp1;
$_keyByte[4*$idx+2] = $_keyByte[4*$idx - 4*$Nk + 2] ^ $tmp2;
$_keyByte[4*$idx+3] = $_keyByte[4*$idx - 4*$Nk + 3] ^ $tmp3;
}
$this->_keyByte = $_keyByte;
}


public function getBlockSize()
{
return 16;
}

// encrypt one 128 bit block
public function encrypt($block, $index=0)
{
$_stateByte = &$this->_stateByte;
$_keyByte = &$this->_keyByte;
$Nb = AESKeyInclude::$Nb;
$_nNr = $this->_nNr;

$_stateByte = array();
$_stateByte = array_merge($_stateByte,array_slice($block,$index,$Nb*4));
$this->addRoundKey($_keyByte, 0);
for ( $round = 1; $round < $_nNr + 1; ++ $round ) {
if ($round < $_nNr) {
$this->mixSubColumns();
} else {
$this->shiftRows();
}
$this->addRoundKey($_keyByte, $round * $Nb * 4);
}
return $_stateByte;
}

public function decrypt($block, $index=0)
{
$_stateByte = &$this->_stateByte;
$_keyByte = &$this->_keyByte;
$Nb = AESKeyInclude::$Nb;
$_nNr = $this->_nNr;

$_stateByte = array();
$_stateByte = array_merge($_stateByte,array_slice($block,$index,$Nb*4));

$this->addRoundKey($_keyByte, $_nNr*$Nb*4);
$this->invShiftRows();
for( $round = $_nNr; $round--; )
{
$this->addRoundKey( $_keyByte, $round*$Nb*4);
if ($round) {
$this->invMixSubColumns();
}
}
return $_stateByte;
}

public function dispose() {

}

// exchanges columns in each of 4 rows
// row0 - unchanged, row1- shifted left 1,
// row2 - shifted left 2 and row3 - shifted left 3
protected function shiftRows()
{
$tmp = 0;

$_stateByte = &$this->_stateByte;
$Sbox = AESKeyInclude::$_Sbox;

// just substitute row 0
$_stateByte[0] = $Sbox[$_stateByte[0]]; $_stateByte[4] = $Sbox[$_stateByte[4]];
$_stateByte[8] = $Sbox[$_stateByte[8]]; $_stateByte[12] = $Sbox[$_stateByte[12]];

// rotate row 1
$tmp = $Sbox[$_stateByte[1]]; $_stateByte[1] = $Sbox[$_stateByte[5]];
$_stateByte[5] = $Sbox[$_stateByte[9]]; $_stateByte[9] = $Sbox[$_stateByte[13]]; $_stateByte[13] = $tmp;

// rotate row 2
$tmp = $Sbox[$_stateByte[2]]; $_stateByte[2] = $Sbox[$_stateByte[10]]; $_stateByte[10] = $tmp;
$tmp = $Sbox[$_stateByte[6]]; $_stateByte[6] = $Sbox[$_stateByte[14]]; $_stateByte[14] = $tmp;

// rotate row 3
$tmp = $Sbox[$_stateByte[15]]; $_stateByte[15] = $Sbox[$_stateByte[11]];
$_stateByte[11] = $Sbox[$_stateByte[7]]; $_stateByte[7] = $Sbox[$_stateByte[3]]; $_stateByte[3] = $tmp;

}

// restores columns in each of 4 rows
// row0 - unchanged, row1- shifted right 1,
// row2 - shifted right 2 and row3 - shifted right 3
protected function invShiftRows ()
{
$tmp = 0;

$_stateByte = $this->_stateByte;
$InvSbox = AESKeyInclude::$_InvSbox;
// restore row 0
$_stateByte[0] = $InvSbox[$_stateByte[0]]; $_stateByte[4] = $InvSbox[$_stateByte[4]];
$_stateByte[8] = $InvSbox[$_stateByte[8]]; $_stateByte[12] = $InvSbox[$_stateByte[12]];

// restore row 1
$tmp = $InvSbox[$_stateByte[13]]; $_stateByte[13] = $InvSbox[$_stateByte[9]];
$_stateByte[9] = $InvSbox[$_stateByte[5]]; $_stateByte[5] = $InvSbox[$_stateByte[1]]; $_stateByte[1] = $tmp;

// restore row 2
$tmp = $InvSbox[$_stateByte[2]]; $_stateByte[2] = $InvSbox[$_stateByte[10]]; $_stateByte[10] = $tmp;
$tmp = $InvSbox[$_stateByte[6]]; $_stateByte[6] = $InvSbox[$_stateByte[14]]; $_stateByte[14] = $tmp;

// restore row 3
$tmp = $InvSbox[$_stateByte[3]]; $_stateByte[3] = $InvSbox[$_stateByte[7]];
$_stateByte[7] = $InvSbox[$_stateByte[11]]; $_stateByte[11] = $InvSbox[$_stateByte[15]]; $_stateByte[15] = $tmp;

$this->_stateByte = $_stateByte;
}

// recombine and mix each row in a column
protected function mixSubColumns ()
{
$_tempByte = array();//.length=0;
$Xtime2Sbox = AESKeyInclude::$_Xtime2Sbox;
$Xtime3Sbox = AESKeyInclude::$_Xtime3Sbox;
$_stateByte = &$this->_stateByte;
$Sbox = AESKeyInclude::$_Sbox;
// mixing column 0
$_tempByte[0] = $Xtime2Sbox[$_stateByte[0]] ^ $Xtime3Sbox[$_stateByte[5]] ^ $Sbox[$_stateByte[10]] ^ $Sbox[$_stateByte[15]];
$_tempByte[1] = $Sbox[$_stateByte[0]] ^ $Xtime2Sbox[$_stateByte[5]] ^ $Xtime3Sbox[$_stateByte[10]] ^ $Sbox[$_stateByte[15]];
$_tempByte[2] = $Sbox[$_stateByte[0]] ^ $Sbox[$_stateByte[5]] ^ $Xtime2Sbox[$_stateByte[10]] ^ $Xtime3Sbox[$_stateByte[15]];
$_tempByte[3] = $Xtime3Sbox[$_stateByte[0]] ^ $Sbox[$_stateByte[5]] ^ $Sbox[$_stateByte[10]] ^ $Xtime2Sbox[$_stateByte[15]];

// mixing column 1
$_tempByte[4] = $Xtime2Sbox[$_stateByte[4]] ^ $Xtime3Sbox[$_stateByte[9]] ^ $Sbox[$_stateByte[14]] ^ $Sbox[$_stateByte[3]];
$_tempByte[5] = $Sbox[$_stateByte[4]] ^ $Xtime2Sbox[$_stateByte[9]] ^ $Xtime3Sbox[$_stateByte[14]] ^ $Sbox[$_stateByte[3]];
$_tempByte[6] = $Sbox[$_stateByte[4]] ^ $Sbox[$_stateByte[9]] ^ $Xtime2Sbox[$_stateByte[14]] ^ $Xtime3Sbox[$_stateByte[3]];
$_tempByte[7] = $Xtime3Sbox[$_stateByte[4]] ^ $Sbox[$_stateByte[9]] ^ $Sbox[$_stateByte[14]] ^ $Xtime2Sbox[$_stateByte[3]];

// mixing column 2
$_tempByte[8] = $Xtime2Sbox[$_stateByte[8]] ^ $Xtime3Sbox[$_stateByte[13]] ^ $Sbox[$_stateByte[2]] ^ $Sbox[$_stateByte[7]];
$_tempByte[9] = $Sbox[$_stateByte[8]] ^ $Xtime2Sbox[$_stateByte[13]] ^ $Xtime3Sbox[$_stateByte[2]] ^ $Sbox[$_stateByte[7]];
$_tempByte[10] = $Sbox[$_stateByte[8]] ^ $Sbox[$_stateByte[13]] ^ $Xtime2Sbox[$_stateByte[2]] ^ $Xtime3Sbox[$_stateByte[7]];
$_tempByte[11] = $Xtime3Sbox[$_stateByte[8]] ^ $Sbox[$_stateByte[13]] ^ $Sbox[$_stateByte[2]] ^ $Xtime2Sbox[$_stateByte[7]];

// mixing column 3
$_tempByte[12] = $Xtime2Sbox[$_stateByte[12]] ^ $Xtime3Sbox[$_stateByte[1]] ^ $Sbox[$_stateByte[6]] ^ $Sbox[$_stateByte[11]];
$_tempByte[13] = $Sbox[$_stateByte[12]] ^ $Xtime2Sbox[$_stateByte[1]] ^ $Xtime3Sbox[$_stateByte[6]] ^ $Sbox[$_stateByte[11]];
$_tempByte[14] = $Sbox[$_stateByte[12]] ^ $Sbox[$_stateByte[1]] ^ $Xtime2Sbox[$_stateByte[6]] ^ $Xtime3Sbox[$_stateByte[11]];
$_tempByte[15] = $Xtime3Sbox[$_stateByte[12]] ^ $Sbox[$_stateByte[1]] ^ $Sbox[$_stateByte[6]] ^ $Xtime2Sbox[$_stateByte[11]];

/*
_stateByte.position=0;
_stateByte.writeBytes(_tempByte, 0, Nb*4);*/

$_stateByte = $_tempByte;

$this->_tempByte = $_tempByte;
}

// restore and un-mix each row in a column
protected function invMixSubColumns ()
{
$_tempByte = array();//.length=0;
$_stateByte = &$this->_stateByte;
$XtimeE = AESKeyInclude::$_XtimeE;
$XtimeB = AESKeyInclude::$_XtimeB;
$Xtime9 = AESKeyInclude::$_Xtime9;
$XtimeD = AESKeyInclude::$_XtimeD;
$InvSbox = AESKeyInclude::$_InvSbox;
$Nb = AESKeyInclude::$Nb;

// restore column 0
$_tempByte[0] = $XtimeE[$_stateByte[0]] ^ $XtimeB[$_stateByte[1]] ^ $XtimeD[$_stateByte[2]] ^ $Xtime9[$_stateByte[3]];
$_tempByte[5] = $Xtime9[$_stateByte[0]] ^ $XtimeE[$_stateByte[1]] ^ $XtimeB[$_stateByte[2]] ^ $XtimeD[$_stateByte[3]];
$_tempByte[10] = $XtimeD[$_stateByte[0]] ^ $Xtime9[$_stateByte[1]] ^ $XtimeE[$_stateByte[2]] ^ $XtimeB[$_stateByte[3]];
$_tempByte[15] = $XtimeB[$_stateByte[0]] ^ $XtimeD[$_stateByte[1]] ^ $Xtime9[$_stateByte[2]] ^ $XtimeE[$_stateByte[3]];

// restore column 1
$_tempByte[4] = $XtimeE[$_stateByte[4]] ^ $XtimeB[$_stateByte[5]] ^ $XtimeD[$_stateByte[6]] ^ $Xtime9[$_stateByte[7]];
$_tempByte[9] = $Xtime9[$_stateByte[4]] ^ $XtimeE[$_stateByte[5]] ^ $XtimeB[$_stateByte[6]] ^ $XtimeD[$_stateByte[7]];
$_tempByte[14] = $XtimeD[$_stateByte[4]] ^ $Xtime9[$_stateByte[5]] ^ $XtimeE[$_stateByte[6]] ^ $XtimeB[$_stateByte[7]];
$_tempByte[3] = $XtimeB[$_stateByte[4]] ^ $XtimeD[$_stateByte[5]] ^ $Xtime9[$_stateByte[6]] ^ $XtimeE[$_stateByte[7]];

// restore column 2
$_tempByte[8] = $XtimeE[$_stateByte[8]] ^ $XtimeB[$_stateByte[9]] ^ $XtimeD[$_stateByte[10]] ^ $Xtime9[$_stateByte[11]];
$_tempByte[13] = $Xtime9[$_stateByte[8]] ^ $XtimeE[$_stateByte[9]] ^ $XtimeB[$_stateByte[10]] ^ $XtimeD[$_stateByte[11]];
$_tempByte[2] = $XtimeD[$_stateByte[8]] ^ $Xtime9[$_stateByte[9]] ^ $XtimeE[$_stateByte[10]] ^ $XtimeB[$_stateByte[11]];
$_tempByte[7] = $XtimeB[$_stateByte[8]] ^ $XtimeD[$_stateByte[9]] ^ $Xtime9[$_stateByte[10]] ^ $XtimeE[$_stateByte[11]];

// restore column 3
$_tempByte[12] = $XtimeE[$_stateByte[12]] ^ $XtimeB[$_stateByte[13]] ^ $XtimeD[$_stateByte[14]] ^ $Xtime9[$_stateByte[15]];
$_tempByte[1] = $Xtime9[$_stateByte[12]] ^ $XtimeE[$_stateByte[13]] ^ $XtimeB[$_stateByte[14]] ^ $XtimeD[$_stateByte[15]];
$_tempByte[6] = $XtimeD[$_stateByte[12]] ^ $Xtime9[$_stateByte[13]] ^ $XtimeE[$_stateByte[14]] ^ $XtimeB[$_stateByte[15]];
$_tempByte[11] = $XtimeB[$_stateByte[12]] ^ $XtimeD[$_stateByte[13]] ^ $Xtime9[$_stateByte[14]] ^ $XtimeE[$_stateByte[15]];

for( $i=0; $i < 4 * $Nb; $i++ )
{
$_stateByte[$i] = $InvSbox[$_tempByte[$i]];
}
}

// encrypt/decrypt columns of the key
protected function addRoundKey ($key, $offset)
{
$_stateByte = &$this->_stateByte;
for( $idx = 0; $idx < 16; ++$idx )
{
$_stateByte[$idx]
^=
$key[$idx+$offset];
}

}

public function toString()
{
return "aes".(8*$this->_keyLength);
}

}
?>



<?php
require_once("IMode.php");
require_once("ICipher.php");
require_once("ISymmetricKey.php");
require_once("PKCS5.php");

class ECBMode implements IMode
{
private $_key;
private $_padding;

public function ECBMode($key/*:ISymmetricKey*/, $padding/*:IPad*/ = NULL)
{
$this->_key = $key;
if ($padding == NULL) {
$padding = new PKCS5($key->getBlockSize());
} else {
$padding->setBlockSize($key->getBlockSize());
}
$this->_padding = $padding;
}

public function getBlockSize() {
return $this->_key->getBlockSize();
}

public function encrypt($src)
{
$src = $this->_padding->pad($src);
$blockSize = $this->_key->getBlockSize();
$dst = array();
$len = count($src);
for ($i=0;$i<$len;$i+=$blockSize) {
//拷贝数据
$tmp = array_slice($src,$i,$blockSize);
$ret = $this->_key->encrypt($tmp);
$dst = array_merge($dst,$ret);
}
return $dst;
}

public function decrypt($src)
{
$blockSize = $this->_key->getBlockSize();

$len = count($src);
// sanity check.
if ($len % $blockSize!=0) {
throw new Exception("ECB mode cipher length must be a multiple of blocksize ".$blockSize);
}

$tmp = array();
$dst = array();

for ($i=0;$i<$len;$i+=$blockSize)
{
$tmp = array_slice($src,$i,$blockSize);
$ret = $this->_key->decrypt($tmp);
$dst = array_merge($dst,$ret);
}
$dst = $this->_padding->unpad($dst);
return $dst;
}

public function dispose()
{

}

public function toString() {
return $this->_key->toString()."-ecb";
}
}
?>





<?php
class Hex
{
static function string2ByteArray($src)
{
//$hex = bin2hex($src);
$ret = array();
$len = strlen($src);
for($i = 0; $i<$len; ++$i)
{
$ret[] = ord($src[$i]);
}
return $ret;
}

static function byteArray2String($src)
{
$ret = "";
$len = count($src);
for($i = 0; $i<$len; ++$i)
{
$ret .= chr($src[$i]);
}

return $ret;
}
}
?>






<?php
interface ICipher
{
function getBlockSize();
function encrypt($src);
function decrypt($src);
function dispose();
function toString();
}
?>




<?php
require_once("ICipher.php");
interface IMode extends ICipher
{
}
?>





<?php
interface IPad
{
/**
* Add padding to the array
*/
function pad($a);
/**
* Remove padding from the array.
* @throws Error if the padding is invalid.
*/
function unpad($a);
/**
* Set the blockSize to work on
*/
function setBlockSize($bs);
}
?>




<?php
interface ISymmetricKey
{
/**
* Returns the block size used by this particular encryption algorithm
*/
function getBlockSize();
/**
* Encrypt one block of data in "block", starting at "index", of length "getBlockSize()"
*/
function encrypt($block, $index);
/**
* Decrypt one block of data in "block", starting at "index", of length "getBlockSize()"
*/
function decrypt($block, $index);
/**
* Attempts to destroy sensitive information from memory, such as encryption keys.
* Note: This is not guaranteed to work given the Flash sandbox model.
*/
function dispose();

function toString();
}
?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值