drk49438 2011-03-25 09:54
浏览 45
已采纳

执行签名Cookie时序列化/反序列化和mcrypt问题

I'm working with a friend to get signed cookies on a website but I'm having a lot of problems when trying to encrypt it with mcrypt and MCRYPT_RIJNDAEL_256. I've the cookies working fine, so the problem is only when encrypting/decrypting the value of the cookie.

Here is the error is showed when trying to decrypt the 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 exact line corresponds to:

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

And here is how I manage to encrypt / decrypt.

First, send 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: Yep, lovely test password ;-)

The value I see on firebug for the cookie is:

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

My get cookie, where I've to decrypt the value is:

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

The problem is when I try to unserialize the value of the decrypted data. Anyone know where can be the problem?

Thank you in advance!

UPDATE:

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

Returns me error Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 0, needed: 32

  • 写回答

2条回答 默认 最新

  • douyi1084 2011-03-25 10:11
    关注

    That offset error normally means that the length of one of the values doesn't correspond to the specified length denoted by the serialized data. In my experience, this normally comes down to:

    • as the previous poster said, backslashes being inserted to escape characters
    • Encoding issues. This normally arises where some characters are computed as having one byte when serialized, but when unserializing they suddenly have 2 bytes. This can happen when you have, say, an ISO-8859-1 character set, but then some operation changes it to UTF-8.

    If I were to take a guess, I'd say that the second point is probably where your problem lies. Your procedure in the first instance is serialize->encrypt->base64_encode, then you reverse the sequence, but I suspect that, somewhere along the line, your character encoding is getting messed up.

    Edited: Okay, I took a look at your code, and there's a problem with your encryption/decryption. Your decryption is not returning the decrypted value back. A while ago I came across this function (wish I could remember where so I can attribute it correctly) which is what I use for Mcrypt. It works for both encode and decode. Try it, and see if it sorts out your problem (the only thing it doesn't do is your base64_encode). I think your problem was that you were missing some required steps.

    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条)

报告相同问题?

悬赏问题

  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?