aes/cbc/pkcs5padding/128加解密示例:
<?php
class AesEncrypt{
//自定义key
protected $key;
//cipher算法类型
protected $cipher = 'rijndael-128';
//mode模型
protected $mode = 'cbc';
public function __construct($key){
$this->key = $key;
}
//aes加密
public function aesEncrypt($data){
//随机生成16位iv,初始向量
$iv = self::aesRandom(16,'1234567890abcdefghijklmnopqrstuvwxyz');
//pkcs5padding
//获取加密算法分组大小
$block = mcrypt_get_block_size($this->cipher, $this->mode);
//方式一 计算补码长度,chr-返回相对应于 ascii 所指定的单个字符
//$pad = chr($block - (strlen($data)%$block));
//str_pad-使用另一个字符串填充字符串为指定长度
//$pad = str_pad($data, ceil(strlen($data)/16.0)*16, $pad);
//方式二 获取补码长度
$pad = $block-(strlen($data)%$block);
//str_repeat-重复一个字符串chr($pad),$pad次
$pad = $data.str_repeat(chr($pad), $pad);
//mcrypt_module_open - 打开算法和模式对应的模块
$td = mcrypt_module_open($this->cipher, '', $this->mode, '');
//mcrypt_generic_init-初始化加密所需的缓冲区
mcrypt_generic_init($td , $this->key , $iv);
//mcrypt_generic- 加密数据,使用前必须调用mcrypt_generic_init
$encrypt = mcrypt_generic($td, $pad);
//mcrypt_generic_deinit — 对加密模块进行清理工作,它会清理缓冲区,但是并不关闭模块
mcrypt_generic_deinit($td);
//mcrypt_module_close — 关闭加密模块
mcrypt_module_close($td);
//iv拼密串之后base64
return base64_encode($iv.$encrypt);
}
//aes解密
public function aesDecrypt($data){
$data = base64_decode($data) ;//base64
//前16位为iv
$iv = substr($data, 0, 16);
//16位后未密串
$data = substr($data, 16);
//mcrypt_module_open - 打开算法和模式对应的模块
$td = mcrypt_module_open($this->cipher, '', $this->mode, '');
//mcrypt_generic_init-初始化加密所需的缓冲区
mcrypt_generic_init($td , $this->key , $iv);
//mdecrypt_generic — 解密数据,使用前必须调用mcrypt_generic_init
$decrypt = mdecrypt_generic($td, $data);
//mcrypt_generic_deinit — 对加密模块进行清理工作
mcrypt_generic_deinit($td);
//mcrypt_module_close — 关闭加密模块
mcrypt_module_close($td);
//Remove the padding
//ord-返回字符的 ASCII 码值
$pad = ord($decrypt[($len = strlen($decrypt))-1]);
//返回补码开始索引位置
$beforePad = strlen($decrypt) - $pad;
//判断是否补码过
$decrypt = substr($decrypt, $beforePad) == str_repeat(substr($decrypt, -1), $pad) ? substr($decrypt, 0, $len - $pad) : $decrypt;
return $decrypt;
}
//随机生成16位iv
public function aesRandom($length, $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789')
{
$hash = '';
$max = strlen($chars) - 1;
for($i = 0; $i < $length; $i++)
{
$hash .= $chars[mt_rand(0, $max)];
}
return $hash;
}
//修改cipher
public function setCipher($cipher){
$this->cipher = $cipher;
}
//修改mode
public function setMode($mode){
$this->mode = $mode;
}
}
//初始化类
$aes = new aesEncrypt('I4fe6xmsndfrGK4g');
$str = 'xiaoming';
//加密
$res = $aes->aesEncrypt($str);
echo $res."<br/>";
//解密
$res2 = $aes->aesDecrypt($res);
echo $res2."<br/>";
$resstr = 'rTnAY7a6vnHkUqfICRxgtiXBYXcP2f+A+zxy4ONsg3w=';
$res3 = $aes->aesDecrypt($resstr);
echo $res3."<br/>";
示例结果:
aesEncrypt: MWY5bzBvOXdidWUxMnU4N/f8ANDZUw3cSza+QCnIquI=
aesDecrypt: xiaoming
aesDecrypt: xiaoming
url后带加密参数获取问题
示例:
http://test.local?token=rTnAY7a6vnHkUqfICRxgtiXBYXcP2f+A+zxy4ONsg3w=
获取以上url后所带参数token
浏览器会将一些特殊字符自动转码,所以获取时需注意转换
1)urldecode
urldecode后将+号转换成空格,需要替换
$token = Input::get('token');
$token = urldecode($token);
echo $token.'<br>';
$token = str_replace(' ','+',$token);
echo $token;
示例结果:
rTnAY7a6vnHkUqfICRxgtiXBYXcP2f A zxy4ONsg3w=
rTnAY7a6vnHkUqfICRxgtiXBYXcP2f+A+zxy4ONsg3w=
2)rawurldecode
$token = Input::get('token');
echo rawurldecode($str);
示例结果:
rTnAY7a6vnHkUqfICRxgtiXBYXcP2f+A+zxy4ONsg3w=