debug = $debug; $this->toHex = $hex; } ////////////////////////////////////////////////////////////////// /* * @function toHexString 把字符串中的每个字符转换成十六进制数 */ function toHexString ($sa) { $buf = ""; for ($i = 0; $i < strlen($sa); $i++) { $val = dechex(ord($sa[$i])); if(strlen($val)< 2) $val = "0".$val; $buf .= $val; } return $buf; } ////////////////////////////////////////////////////////////////// /* * @function fromHexString 把十六进制数转换成字符串 */ function fromHexString($sa) { $buf = ""; for($i = 0; $i < strlen($sa); $i += 2) { $val = chr(hexdec(substr($sa, $i, 2))); $buf .= $val; } return $buf; } ////////////////////////////////////////////////////////////////// /* * @function showInt 输出调试信息 */ function showInt($texto) { if($this->debug) { echo($texto.": "); for($i = 0; $i<4; $i++) { for($j = 0; $j<4; $j++) { echo(dechex($this->state[$j][$i])." "); } } echo ("
"); } } ////////////////////////////////////////////////////////////////// /* * @function makeKey 密钥扩展(128bit) * @param hash 密钥 * @return array 返回三维数组 */ function makeKey($hash) { if(strlen($hash) < 16) for($i = strlen($hash); $i < 16; $i++) $hash .= " "; $rconpocharer = 0; $tk = array(array());; $rk = array(array(array())); for($j = 0; $j < $this->Nk; $j++) for($i = 0; $i < 4; $i++) $tk[$i][$j] = ord($hash[$j*4+$i]) > 256 ? ord($hash[$j*4+$i])%256 : ord($hash[$j*4+$i]);// 转换成ASCII码值 $t = 0; for($j = 0; ($j < $this->Nk) && ($t < ($this->Nr+1)*$this->Nb); $j++, $t++) for($i = 0; $i < 4; $i++) $rk[$t / $this->Nb][$i][$t % $this->Nb] = $tk[$i][$j]; while ($t < ($this->Nr+1)*$this->Nb) { for($i = 0; $i < 4; $i++) $tk[$i][0] ^= $this->S[$tk[($i+1)%4][$this->Nk-1]]; $tk[0][0] ^= $this->rcon[$rconpocharer++]; for($j = 1; $j < $this->Nk; $j++) for($i = 0; $i < 4; $i++) $tk[$i][$j] ^= $tk[$i][$j-1]; for($j = 0; ($j < $this->Nk) && ($t < ($this->Nr+1)*$this->Nb); $j++, $t++) for($i = 0; $i < 4; $i++) $rk[$t / $this->Nb][$i][$t % $this->Nb] = $tk[$i][$j]; } return $rk; } ////////////////////////////////////////////////////////////////// /* * @function: encryptString 加密字符串 * @param: excodeStr 被加密的字符串 * @param: expandedKeys 扩展后的密钥 * @return: 返回加密后的字符串 */ function encryptString($excodeStr, $expandedKeys) { if(strlen($excodeStr) % 16 == 0 ) $cnt = strlen($excodeStr) /16; else { $cnt = ceil(strlen($excodeStr) /16); for($i = strlen($excodeStr); $i < $cnt *16; $i++) $excodeStr .= " "; } $out = ""; for($i = 0; $i < $cnt; $i++) $out .= $this->blockEncrypt(substr($excodeStr,$i*16,16), $expandedKeys); if($this->toHex) $out = $this->toHexString($out); return $out; } ////////////////////////////////////////////////////////////////// /* * @function blockEncrypt 分块加密 */ function blockEncrypt($in, $keys) { for ($i = 0; $i < 4; $i++) for ($j = 0; $j < $this->Nb; $j++) $this->state[$j][$i] = ord($in[$i*4+$j]); $this->showInt("Cifrado:
State Inicial"); $this->KeyAddition($keys[0]); $this->showInt("Ronda 0 :: KeyAddition"); for($r = 1; $r < $this->Nr; $r++) { $this->ByteSubShiftRow(); $this->showInt("Ronda $r :: ByteSubShiftRow"); $this->MixColumnKeyAddition($keys[$r]); $this->showInt("Ronda $r :: MixColumnKeyAddition"); } $this->ByteSubShiftRow(); $this->showInt("Ronda final :: ByteSubShiftRow"); $this->KeyAddition($keys[$this->Nr]); $this->showInt("Ronda final :: KeyAddition ==> Resultado"); $out = ""; for($i = 0; $i < 4; $i++) for ($j = 0; $j < 4; $j++) $out .=chr($this->state[$j][$i]); return $out; } ////////////////////////////////////////////////////////////////// /* * @function: decryptString 解密字符串 * @param: decodeStr 被解密的字符串 * @param: expandedKeys 扩展后的密钥 * @return: 返回解密后的字符串 */ function decryptString($decodeStr, $expandedKeys) { if($this->toHex) $decodeStr = $this->fromHexString($decodeStr); if(strlen($decodeStr) % 16 == 0 ) $cnt = strlen($decodeStr) /16; else return; $out = ""; for($i = 0; $i < $cnt; $i++) { $out .= $this->blockDecrypt(substr($decodeStr,$i*16,16),$expandedKeys); } return trim($out); } ////////////////////////////////////////////////////////////////// /* * @function blockDecrypt 分块解密 */ function blockDecrypt($in, $keys) { for ($i = 0; $i < 4; $i++) for ($j = 0; $j < $this->Nb; $j++) $this->state[$j][$i] = ord($in[$i*4+$j]); $this->showInt("Descifrado:
State Inicial"); $this->KeyAddition($keys[$this->Nr]); $this->showInt("Ronda 0 :: KeyAddition"); for($r = $this->Nr-1; $r > 0; $r--) { $this->InvShiftRowInvByteSub(); $this->showInt("Ronda ". ($this->Nr - $r)." :: InvShiftRowInvByteSub"); $this->KeyAddition($keys[$r]); $this->showInt("Ronda ".($this->Nr - $r)." :: KeyAddition"); $this->InvMixColumn(); $this->showInt("Ronda ".($this->Nr - $r)." :: InvMiColumn"); } $this->InvShiftRowInvByteSub(); $this->showInt("Ronda final :: InvShiftRowInvByteSub"); $this->KeyAddition($keys[0]); $this->showInt("Ronda final :: KeyAddition ==> Resultado"); $out = ""; for($i = 0; $i < 4; $i++) for ($j = 0; $j < 4; $j++) $out .= chr($this->state[$j][$i]); return $out; } ////////////////////////////////////////////////////////////////// /* * @function ByteSubShiftRow 作用在状态中每个字节上的一种非线性字节转换 */ function ByteSubShiftRow() { $tmp = array(array()); for($i = 0; $i < 4; $i++) for($j = 0; $j < $this->Nb; $j++) $tmp[$i][$this->shifts_r[$i][$j]] = $this->S[$this->state[$i][$j]]; $this->state = $tmp; } ////////////////////////////////////////////////////////////////// /* * @function KeyAddition 将圈密钥状态中的对应字节按位"异或" */ function KeyAddition($rk) { for($i = 0; $i < 4; $i++) for($j = 0; $j < $this->Nb; $j++) $this->state[$i][$j] ^= $rk[$i][$j]; } ///////////////////////////////////////////////////////////////// /* * @function InvShiftRowInvByteSub 作用在状态中每个字节上的一种非线性字节反转换,与ByteSubShiftRow()互逆 */ function InvShiftRowInvByteSub() { $tmp = array(array()); for($i = 0; $i < 4; $i++) for($j = 0; $j < $this->Nb; $j++) $tmp[$i][$this->shifts_l[$i][$j]] = $this->Si[$this->state[$i][$j]]; $this->state = $tmp; } ////////////////////////////////////////////////////////////////// /* * @function MixColumnKeyAddition 混合列变换 */ function MixColumnKeyAddition($rk) { $b = array(array()); for($j = 0; $j < 4; $j++) for($i = 0; $i < $this->Nb; $i++) { $b[$i][$j] = $this->T2[$this->state[$i][$j]] ^ $this->T3[$this->state[($i + 1) % 4][$j]] ^ $this->state[($i + 2) % 4][$j] ^ $this->state[($i + 3) % 4][$j]; $b[$i][$j] ^= $rk[$i][$j]; } $this->state = $b; } ////////////////////////////////////////////////////////////////// /* * @function InvMixColumn 混合列逆变换 */ function InvMixColumn() { $b = array(array()); for($j = 0; $j < 4; $j++) for($i = 0; $i < $this->Nb; $i++) $b[$i][$j] = $this->T14[$this->state[$i][$j]] ^ $this->T11[$this->state[($i + 1) % 4][$j]] ^ $this->T13[$this->state[($i + 2) % 4][$j]] ^ $this->T9[$this->state[($i + 3) % 4][$j]]; $this->state = $b; } ////////////////////////////////////////////////////////////////// /* * @function encryptFile * @param:sourcePath 文件所在目录的绝对路径 * @param: filename 被加密的文件名称 * @param: expandKeys 扩展后的密钥 * @param:destPath 存放加密后的文件绝对路径 * @param: encodeFile 加密后的文件名称 * @return: boolean */ function encryptFile($sourcePath, $filename, $expandKeys, $destPath = "", $encodeFile = "") { $destPath = $sourcePath; $encodeFile = "en".$filename; } } /* //$aes = new AES(); $aes = new AES(true);// 把加密后的字符串按十六进制进行存储 //$aes = new AES(true,true);// 带有调试信息且加密字符串按十六进制存储 $key = "this is a 32 byte key";// 密钥 $keys = $aes->makeKey($key); $encode = serialize(array('test1'=>'你好','test2'=>'yes'));// 被加密的字符串 $ct = $aes->encryptString($encode, $keys); echo "encode = ".$ct."\n"; $cpt = $aes->decryptString($ct, $keys); echo "decode = ".print_r(unserialize($cpt)); */ ?>