Part of the EllisLab Network
   
 
Encryption Problem with mbstring
Posted: 19 September 2008 08:19 AM   [ Ignore ]  
Research Assistant
RankRankRank
Total Posts:  325
Joined  09-09-2007

Does anyone have any experience getting the encryption library to work with the mbstring functions fully overloaded?  I get decryption errors saying:

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.

 Signature 

Zenedy | Anyvite | Tweetvite

Profile
 
 
Posted: 19 September 2008 02:11 PM   [ Ignore ]   [ # 1 ]  
Research Assistant
RankRankRank
Total Posts:  325
Joined  09-09-2007

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?

 Signature 

Zenedy | Anyvite | Tweetvite

Profile
 
 
Posted: 19 September 2008 03:07 PM   [ Ignore ]   [ # 2 ]  
Grad Student
Rank
Total Posts:  33
Joined  02-08-2008

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.

 Signature 
Profile
 
 
Posted: 19 September 2008 09:58 PM   [ Ignore ]   [ # 3 ]  
Research Assistant
RankRankRank
Total Posts:  325
Joined  09-09-2007

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.

 Signature 

Zenedy | Anyvite | Tweetvite

Profile
 
 
Posted: 20 September 2008 09:51 PM   [ Ignore ]   [ # 4 ]  
Research Assistant
RankRankRank
Total Posts:  325
Joined  09-09-2007

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:

/**
     * 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($data0$init_size'latin1');
        
$data mb_substr($data$init_sizemb_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;
    
 Signature 

Zenedy | Anyvite | Tweetvite

Profile
 
 
Posted: 04 June 2010 10:39 AM   [ Ignore ]   [ # 5 ]  
Summer Student
Total Posts:  3
Joined  04-24-2007

@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:
http://www.haughin.com/2010/02/23/building-utf8-compatible-codeigniter-applications/

And Phil Sturgeon’s equally helpful article:
http://philsturgeon.co.uk/news/2009/08/UTF-8-support-for-CodeIgniter

I found that my error log had the message:

SeverityNotice  --> 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!

Profile
 
 
Posted: 20 October 2010 09:16 PM   [ Ignore ]   [ # 6 ]  
Summer Student
Total Posts:  26
Joined  02-12-2010

I have had the same problems, same error messages in the log causing big issues with my site; I found that i had

mbstring.func_overload 

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

Profile
 
 
Posted: 20 October 2010 09:26 PM   [ Ignore ]   [ # 7 ]  
Research Assistant
RankRankRank
Total Posts:  325
Joined  09-09-2007

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.

 Signature 

Zenedy | Anyvite | Tweetvite

Profile
 
 
   
 
 
‹‹ Strange redirect() problem      date problem ››