13

I have a bit of a weird one in this class:

<?php
namespace lib;

/**
 * Short description of Crypt
 *
 * @author xxxx
 * @package
 */
class Encryption
{
    /**
     * Short description of _ch
     * handle to the mcrypt resource
     *
     * @access private
     * @var $_ch
     */
    private $_ch;

    /**
     * Short description of __construct
     *
     * @access public
     * @author xxxx
     * @param
     * @return void
     */
    public function __construct( $keyData = NULL, $algorithm = \MCRYPT_RIJNDAEL_256, $mode = MCRYPT_MODE_ECB, $encLibPath = '', $modeDir = '' )
    {
        $this->_ch = mcrypt_module_open( $algorithm, $encLibPath, $mode, $modeDir );

        $vector  = mcrypt_create_iv ( mcrypt_enc_get_iv_size( $this->_ch ), \MCRYPT_DEV_URANDOM );
        $keySize = mcrypt_enc_get_key_size( $this->_ch );

        $key = substr( hash( 'SHA512', $keyData . $keySize ), 0, $keySize );

        $x = mcrypt_generic_init( $this->_ch, $key, $vector );
    }

    /**
     * Short description of encrypt
     *
     * @access public
     * @author xxxx
     * @param String $str
     * @return String $res
     */
    public function encrypt( $str )
    {
        if( !is_string( $str ) )
        {
            throw new \InvalidArgumentException( 'Attemptig to encrypt data that is not a string' );
            return false;
        }
        $res = mcrypt_generic( $this->_ch, $str );

        mcrypt_generic_deinit( $this->_ch );
        mcrypt_module_close( $this->_ch );

        #var_dump($str,$res);
        return $res;
    }

    /**
     * Short description of decrypt
     *
     * @access public
     * @author xxxx
     * @param String $str
     * @return String $res
     */
    public function decrypt( $str )
    {
        if( !is_string( $str ) )
        {
            throw new \InvalidArgumentException( 'Attemptig to decrypt data that is not a string' );
            return false;
        }

82      $res = mdecrypt_generic( $this->_ch, $str );

84      mcrypt_generic_deinit( $this->_ch );
85      mcrypt_module_close( $this->_ch );

        #var_dump($str,$res);
        return trim( $res);
    }
}

when calling this like so:

<?php
$encryption    = new \lib\Encryption( 'somekey' );

echo $encryption->decrypt( $safeInfo );

strangle yields:

Warning: mdecrypt_generic(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 82

Warning: mcrypt_generic_deinit(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 84

Warning: mcrypt_module_close(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 85

(these lines are shown in the encryption class.)

AND

the expected decrypted string (as in successfully decrypted).

I would be grateful to anyone who might point out why the warnings are raised and why it doesn't seem to affect the outcome.

PS any comments on the effectiveness of the encryption class most welcome.

hakre
  • 193,403
  • 52
  • 435
  • 836
Ian Wood
  • 6,515
  • 5
  • 34
  • 73
  • What is the value of `$this->_ch`? – jeroen May 14 '12 at 14:18
  • var_dump( $this->_ch ) yields resource(90, mcrypt) – Ian Wood May 14 '12 at 14:21
  • I tried running your script on both Linux and Windows. I didn't get any warnings. I made sure to turn all errors on too. I wasn't able to reproduce the same result. If I call mycrypt_module_close first, then it would show the warnings, but not decrypt. – Gohn67 May 19 '12 at 02:01
  • Also I tried running var_dump on $this->_ch in the constructor. My result was slightly different than yours. I got `resource(2) of type (mcrypt)` – Gohn67 May 19 '12 at 02:02
  • @Gohn67 - thats still a mcrypt resources - It might be down to version or xdebug on how teh var_dump is outputted but its saying that it is a an mcrypt resource... – Ian Wood May 19 '12 at 11:38
  • @IanWood Maybe the warning is specific to your stack? Seems like you're on Windows. What specific version of php are you running? Seems like > 5.3 since you're using namespaces. I think that means a version of the mcrypt extension comes installed by default. Also did you install with say WAMP or XAMPP? I ran your code on Windows 7, PHP 5.3.2 TS version, no xdebug. – Gohn67 May 19 '12 at 17:09
  • @gohn67 - php 5.3.6, apache 2.2.17, win7 ultimate. NO WAMP (should be banned in my book ;)) I'll dig some more tomorrow. – Ian Wood May 20 '12 at 10:46
  • I was able to test your script on another system. Win7 Pro with PHP 5.3.4 and mcrypt 2.5.8. Didn't get any warnings. On my Win7 Home, I also had mcrypt 2.5.8. Maybe it is your version of mcrypt. However I would be surprised if it wasn't 2.5.8 since it is installed with PHP 5.3+ and you don't need the dll anymore like in PHP < 5.3 – Gohn67 May 22 '12 at 18:08
  • Just another question - do you get the error if you do a straight "Create mctypt, encrypt, destrpy, create mycrypt, decrypt, destroy" in one straight PHP file (no class, no nothing else)? If that works, gives you somewhere to start build up from. – Robbie May 23 '12 at 23:58

3 Answers3

5

it looks well

<?php
$encryption = new \lib\Encryption( 'somekey' );
echo $encryption->decrypt(pack("H*", "4a4a564f26618d47536ff35b8a0af3212814a5f0ba635d2cf6f8cd31589042e2"));

_ch lost beacuse mcrypt_module_close( $this->_ch ); in method encrypt()

Maybe you can change __construct and save args only, just create handle ( like _ch ) when you encrypt or decrypt every time.

I'm not good at Mcrypt, so maybe some batter way than mine, but the reason of "valid MCrypt resource" problem is truly mcrypt_module_close

Zheng Kai
  • 3,473
  • 3
  • 17
  • 23
  • Just the fact that `mcrypt_module_close` is there? It's not called until after en/decryption is done and its never called on the same object so you can't encode and decode in the same instance... – Ian Wood May 17 '12 at 12:52
  • 1
    If you do encrypt followed by decrypt you will get the warnings, but does not print the correct result. I think it stops before it can decrypt. I was able to reproduce the warnings and the correct result only be calling decrypt twice in a row so far. The correct string appears first, then the warnings. – Gohn67 May 23 '12 at 17:34
3

Looks like a namespace issue since you didn't prefix MCRYPT_MODE_ECB in __construct().

Botz3000
  • 39,020
  • 8
  • 103
  • 127
fsimon
  • 171
  • 1
  • 3
  • That turns out not to be a problem in this case since he didn't use `use some_namespace`, so the class is still in the global namespace, whic is why `MCRYPT_MODE_ECB` works without a `\`. I could be wrong though. I'm not completely familiar with namespaces in php. – Gohn67 May 20 '12 at 18:53
2

This is something to check, but as I can't reproduce, not sure if it's the answer.

You have SHA512 (creating a 512 length key) but the algorythm is expecting a 256 length key. Does it make any difference if you use SHA256? Normally a mismatch in keys should produce garbage, but in this case it may still be working "with side effects".

Robbie
  • 17,605
  • 4
  • 35
  • 72
  • No it doesn't matter in this case as the substr function takes care of that - it will makes sure the length of the key is appropriate. – Ian Wood May 22 '12 at 21:57