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 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)