我正在尝试这个脚本,但字符编码不断变化:
$v1 = "text1";
$v2 = "text2";
$v3 = "text3";
$result = encrypt($v1 . ":" . $v2 . ":" . $v3, SALT);
$result = decrypt($result , SALT);
list($v1, $v2, $v3) = explode(":", $result);
echo mb_detect_encoding($v1); // gives ASCII
echo mb_detect_encoding($v2); // gives ASCII
echo mb_detect_encoding($v3); // gives UTF-8 <<<<
但是通过添加另一个var,它会给出:
$v1 = "text1";
$v2 = "text2";
$v3 = "text3";
$result = encrypt($v1 . ":" . $v2 . ":" . $v3. ":COTROLFLAG", SALT);
$result = decrypt($result , SALT);
list($v1, $v2, $v3, $v4) = explode(":", $result);
echo mb_detect_encoding($v1); // gives ASCII
echo mb_detect_encoding($v2); // gives ASCII
echo mb_detect_encoding($v3); // gives ASCII <<<<
echo mb_detect_encoding($v4); // gives ASCII
任何人都可以帮助我吗?
这些是加密和解密功能:
function encrypt($str, $key)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$block = mcrypt_get_block_size('des', 'ecb');
if (($pad = $block - (strlen($str) % $block)) < $block) {
$str .= str_repeat(chr($pad), $pad);
}
$result = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $str, MCRYPT_MODE_ECB, $iv));
return $result;
}
function decrypt($str, $key)
{
$str = base64_decode($str);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $str, MCRYPT_MODE_ECB, $iv);
$block = mcrypt_get_block_size('des', 'ecb');
$pad = ord($str[($len = strlen($str)) - 1]);
if ($pad && $pad < $block && preg_match('/' . chr($pad) . '{' . $pad . '}$/i', $str)) {
return substr($str, 0, strlen($str) - $pad);
}
return $str;
}
在第一个答案之后,我知道应该在哪里寻找解决方案..
我发现这是为了填充和剥离:
function addpadding($string, $blocksize = 32){
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
function strippadding($string){
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if(preg_match("/$slastc{".$slast."}/", $string)){
$string = substr($string, 0, strlen($string)-$slast);
return $string;
} else {
return false;
}
}
更改的加密和解密功能:
function encrypt($str, $key)
{
global $domain;
$key = base64_decode($key);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
setcookie("IV_CODE", $iv, time()+86400, "/", $domain);//more security
$enc = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, addpadding($str), MCRYPT_MODE_CBC, $iv));
return $enc;
}
function decrypt($str, $key)
{
$str = base64_decode($str);
$iv = (isset($_COOKIE['IV_CODE'])) ? base64_decode($_COOKIE['IV_CODE']) : 0;
if ($iv != 0) {
$key = base64_decode($key);
$dec = strippadding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $str, MCRYPT_MODE_CBC, $iv));
return $dec;
}
return false;
}
谢谢
答案 0 :(得分:1)
这与爆炸无关,它是你的加密和解密功能。我会冒险猜测并说出这个
if (($pad = $block - (strlen($str) % $block)) < $block) {
$str .= str_repeat(chr($pad), $pad);
}
与this post on php.net中AES_256
提及的内容有关。 (你应该记住它对MCRYPT_RIJNDAEL_128
的说法)
但是,decrypt()
函数中的代码存在很多问题。例如,如果填充长度为27
,则您的正则表达式模式很容易被破坏。它也绝对不应该不区分大小写。但是,提取子字符串并使用==
之类的
$substr = substr($str, -$pad);
if ($pad && $pad < $block && $substr == str_repeat(chr($pad), $pad)) {
return substr($str, 0, -$pad);
}