2

我正在尝试这个脚本,但字符编码不断变化:

    $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;
}

谢谢你

4

1 回答 1

1

这与爆炸无关,这是您的加密和解密功能。我会冒险猜测并说这个

if (($pad = $block - (strlen($str) % $block)) < $block) {
    $str .= str_repeat(chr($pad), $pad);
}

与php.net 上这篇文章AES_256中提到的内容有关。(您可能也应该记住它所说的内容)MCRYPT_RIJNDAEL_128

但是,函数中的代码有很多错误decrypt()。例如,如果填充长度为 ,则您的正则表达式模式很容易被破坏27。它也不应该是不区分大小写的。但是,仅提取子字符串并使用==like进行比较可能更容易而且肯定更快

$substr = substr($str, -$pad);
if ($pad && $pad < $block && $substr == str_repeat(chr($pad), $pad)) {
    return substr($str, 0, -$pad);
}
于 2013-01-17T23:46:37.417 回答