我正在和一位朋友一起在网站上获取已签名的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:是的,可爱的测试密码; - )
我在firebug上看到的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
答案 0 :(得分:2)
该偏移误差通常意味着其中一个值的长度与序列化数据表示的指定长度不对应。根据我的经验,这通常归结为:
如果我猜测,我会说第二点可能就是你的问题所在。您在第一个实例中的过程是serialize-> encrypt-> 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;
}
答案 1 :(得分:0)
确保使用反斜杠不转义Cookie信息中的引号"
。如果他们的报价已被转义,请在加密前将其删除。看到这个主题 - > PHP unserialize error at offset, works on some servers, not others