0

我正在和朋友一起在网站上获取签名的 cookie,但是在尝试使用 mcrypt 和 MCRYPT_RIJNDAEL_256 对其进行加密时遇到了很多问题。我的 cookie 工作正常,所以问题只出在加密/解密 cookie 的值时。

这是尝试解密 cookie 时显示的错误:

Notice: unserialize(): Error at offset 0 of 93 bytes in /var/samba/www/xxx/src/data/include/yyy/Cookie.php on line 94

这条确切的线对应于:

$this->_cookie["value"] =  unserialize(mdecrypt_generic($tv, $cookie_value));

这就是我设法加密/解密的方法。

首先,发送cookie。

    $tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
    mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);

    $this->_cookie["value"] =  base64_encode(mcrypt_generic($tv, serialize($this->_cookie["value"])));

    mcrypt_generic_deinit($tv);
    mcrypt_module_close($tv);

    setrawcookie($this->_cookie["name"],
                 $this->_cookie["value"],
                 $this->_cookie["expire"],
                 $this->_cookie["path"],
                 $this->_cookie["domain"],
                 $this->_cookie["secure"],
                 $this->_cookie["httponly"]);

PD:是的,可爱的测试密码 ;-)

我在萤火虫上看到的 cookie 值是:

oKWdbVLX9T+mbOut4swo/aXr0g5O/3ApqfWZ1GZlrwwMSTa+M4n8Uey0UQs827HB7tilc/OzUPWQxoNvnAIkP5CFGkvgn+j+I36qN6dB0HmOUPlkNXJlz8Tfqxrjf8Gx

我的获取cookie,我必须解密的值是:

    $this->_cookie["name"] = $cookie_name;
    $this->_cookie["value"] = $_COOKIE[$cookie_name];

    $cookie_value = base64_decode($this->_cookie["value"]);

    $tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
    mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);

    $this->_cookie["value"] =  unserialize(mdecrypt_generic($tv, $cookie_value));

    mcrypt_generic_deinit($tv);
    mcrypt_module_close($tv);

    return $_COOKIE[$cookie_name];

问题是当我尝试反序列化解密数据的值时。有谁知道问题出在哪里?

先感谢您!

更新:

    $cookie_value = base64_decode($this->_cookie["value"]);

    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, "", "cfb", "");
    $ks = mcrypt_enc_get_key_size($td);
    $key = substr(sha1("t3stp4ssw0rd"), 0, $ks);

    $ivs = mcrypt_enc_get_iv_size($td);
    $iv = substr($cookie_value, 0, $ivs);

    $cookie_value = substr($cookie_value, $ivs);

    mcrypt_generic_init($td, $key, $iv);

    $cookie_value = mdecrypt_generic($td, $cookie_value);

    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);

    $this->_cookie["value"] =  unserialize($cookie_value);

返回我错误Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 0, needed: 32

4

2 回答 2

2

该偏移错误通常意味着其中一个值的长度与序列化数据表示的指定长度不对应。根据我的经验,这通常归结为:

  • 正如之前的海报所说,插入反斜杠以转义字符
  • 编码问题。这通常发生在某些字符在序列化时被计算为具有一个字节,但在反序列化时它们突然具有 2 个字节的情况。例如,当您拥有 ISO-8859-1 字符集,但随后某些操作将其更改为 UTF-8 时,就会发生这种情况。

如果我猜测,我会说第二点可能是您的问题所在。您的程序首先是序列化->加密->base64_encode,然后您颠倒顺序,但我怀疑在某处,您的字符编码会变得混乱。

编辑: 好的,我看了你的代码,你的加密/解密有问题。您的解密不会返回解密的值。不久前,我遇到了这个函数(希望我能记住在哪里,以便我可以正确地对其进行归因),这是我用于 Mcrypt 的。它适用于编码和解码。试试看,看看它是否能解决你的问题(它唯一没有做的就是你的 base64_encode)。我认为您的问题是您缺少一些必需的步骤。

function encDec( $data, $key, $encrypt=true, $cypher='rijndael-128') {

    if (function_exists('mcrypt_module_open')) {

        # Serialize, if encrypting
        if ( $encrypt ) { $data = serialize($data); } 

        # Open cipher module
        if ( ! $td = mcrypt_module_open($cypher, '', 'cfb', '') )
            return false;

        $ks = mcrypt_enc_get_key_size($td);     # Required key size
        $key = substr(sha1($key), 0, $ks);      # Harden / adjust length

        $ivs = mcrypt_enc_get_iv_size($td);     # IV size

        $iv = $encrypt ?
            mcrypt_create_iv($ivs, MCRYPT_RAND) :   # Create IV, if encrypting
            substr($data, 0, $ivs);                 # Extract IV, if decrypting

        # Extract data, if decrypting
        if ( ! $encrypt ) $data = substr($data, $ivs);

        if ( mcrypt_generic_init($td, $key, $iv) !== 0 ) # Initialize buffers
            return false;

        $data = $encrypt ?
            mcrypt_generic($td, $data) :    # Perform encryption
            mdecrypt_generic($td, $data);   # Perform decryption

        if ( $encrypt ) $data = $iv . $data;    # Prepend IV, if encrypting

        mcrypt_generic_deinit($td);             # Clear buffers
        mcrypt_module_close($td);               # Close cipher module

        # Unserialize, if decrypting
        if ( ! $encrypt ) $data = unserialize($data);

    }

    return $data;
}
于 2011-03-25T10:11:48.307 回答
0

Make sure the quotes " in the cookie information are not escaped using back slashes. If they quotes are escaped, remove them before encrypting. See this thread -> PHP unserialize error at offset, works on some servers, not others

于 2011-03-25T10:00:58.407 回答