• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Encryption Problem with mbstring

#1
[eluser]dmorin[/eluser]
Does anyone have any experience getting the encryption library to work with the mbstring functions fully overloaded? I get decryption errors saying:

Quote:mcrypt_decrypt() [function.mcrypt-decrypt]: The IV parameter must be as long as the blocksize

Would really appreciate the help if you have any ideas. Thanks.

#2
[eluser]dmorin[/eluser]
Just an update, I only get that error sometimes, so that's just part of the problem. Still trying to break down how the encryption library works to troubleshoot it.

Does anyone know of another encryption library that I should just use or maybe the mcrypt functions on their own?

#3
[eluser]outrage[/eluser]
Forgive me if I'm wrong, but I seem to remember having problems with encryption when I turned gzip compression on. I can't for the life of me remember whether it was mcrypt or not though, I switched to sha1 and everything was fine.

#4
[eluser]dmorin[/eluser]
Thanks for the reply. Unfortunately I'm not using gzip and need to decrypt things instead of just hashing.

I haven't had much time to look into it, but I've narrowed it down to the IV in the decrypt potion being too long. Will post here when/if I figure out a solution.

#5
[eluser]dmorin[/eluser]
If anyone has this same problem in the future, the solution is to replace the strlen($var) function calls with mb_strlen($var, 'latin1'). This will cause mb_strlen to act like the original strlen function. You also need to do it to a few of the substr calls also as the 4th parameter. Here is my code:

Code:
/**
     * Decrypt using Mcrypt
     *
     * @access    public
     * @param    string
     * @param    string
     * @return    string
     */    
    function mcrypt_decode($data, $key)
    {        
        $data = $this->_remove_cipher_noise($data, $key);
        $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
        if ($init_size > mb_strlen($data, 'latin1'))
        {
            return FALSE;
        }
        
        $init_vect = mb_substr($data, 0, $init_size, 'latin1');
        $data = mb_substr($data, $init_size, mb_strlen($data, 'latin1'), 'latin1');
        return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");
    }
      
    // --------------------------------------------------------------------

    /**
     * Adds permuted noise to the IV + encrypted data to protect
     * against Man-in-the-middle attacks on CBC mode ciphers
     * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
     *
     * Function description
     *
     * @access    private
     * @param    string
     * @param    string
     * @return    string
     */
    function _add_cipher_noise($data, $key)
    {
        $keyhash = $this->hash($key);
        $keylen = strlen($keyhash);
        $str = '';
    
        for ($i = 0, $j = 0, $len = mb_strlen($data, 'latin1'); $i < $len; ++$i, ++$j)
        {    
            if ($j >= $keylen)
            {
                $j = 0;
            }
            
            $str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);
        }
        
        return $str;
    }

    // --------------------------------------------------------------------
    
    /**
     * Removes permuted noise from the IV + encrypted data, reversing
     * _add_cipher_noise()
     *
     * Function description
     *
     * @access    public
     * @param    type
     * @return    type
     */
    function _remove_cipher_noise($data, $key)
    {
        $keyhash = $this->hash($key);
        $keylen = mb_strlen($keyhash, 'latin1');
        $str = '';

        for ($i = 0, $j = 0, $len = mb_strlen($data, 'latin1'); $i < $len; ++$i, ++$j)
        {
            if ($j >= $keylen)
            {
                $j = 0;
            }
            
            $temp = ord($data[$i]) - ord($keyhash[$j]);
            
            if ($temp < 0)
            {
                $temp = $temp + 256;
            }
            
            $str .= chr($temp);
        }
        
        return $str;
    }

#6
[eluser]jingman[/eluser]
@dmorin - thank you for figuring this out, this saved me. A little description to help future-searchers find this post:

After enabling mbstring to get UTF-8 support via Elliot Haughin's awesome article:
<a href="http://www.haughin.com/2010/02/23/building-utf8-compatible-codeigniter-applications/">http://www.haughin.com/2010/02/23/building-utf8-compatible-codeigniter-applications/</a>

And Phil Sturgeon's equally helpful article:
<a href="http://philsturgeon.co.uk/news/2009/08/UTF-8-support-for-CodeIgniter">http://philsturgeon.co.uk/news/2009/08/UTF-8-support-for-CodeIgniter</a>

I found that my error log had the message:
Code:
Severity: Notice  --&gt; unserialize() [<a href='function.unserialize'>function.unserialize</a>]: Error at offset 0 of 48 bytes ../system/libraries/Session.php 708

After some debugging, I found that the session cookie was not being encoded/decoded properly.

Extending the Encryption library (using MY_Encrypt) with @dmorin's code solved the problem.

Thanks again!

#7
[eluser]packetfox[/eluser]
I have had the same problems, same error messages in the log causing big issues with my site; I found that i had

Code:
mbstring.func_overload = 7

in my php.ini, and setting that back to 0 fixed the problem for me.

#8
[eluser]dmorin[/eluser]
Sure, removing the mb_string function overloading will solve the problem, but it also means you have to explicitly use the mb_string functions if you're dealing with any non-ascii characters which wasn't an option for me.

#9
[eluser]Unknown[/eluser]
mbstring.func_overload = 0 fixed my problem... thanks paketfox!


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.