11

I am having an issue with my cipher class. At times it is very fast. Sometimes however it is slow. the code Im using is as follows

class Cipher {
    private $securekey, $iv;
    function __construct() {
        $this->securekey = hash('sha256','51(^8k"12cJ[6&cvo3H/!2s02Uh46vuT4l7sc7a@cZ27Q',TRUE);
        $this->iv = mcrypt_create_iv(32);
    }
    function encrypt($input) {
        return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->securekey, $input, MCRYPT_MODE_ECB));
    }
    function decrypt($input) {
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB));
    }
    function storeIV() {
        return $this->iv;
    }
}

Are there any suggestions on why this may be slow at times and how I could fix this?

bretterer
  • 5,693
  • 5
  • 32
  • 53
  • What is server load like when it runs fast? When it runs slow? What kinds of times have you recorded? – WWW Jun 06 '12 at 15:22
  • Server loads have been identical between fast/slow when it is quick it is loading in about .5 seconds when it is slow, I can wait for about 2 minutes – bretterer Jun 06 '12 at 15:24
  • Just a security note: I believe you are using your Cipher class to encrypt multiple plaintext. Normally an iv should not be reused, so it is better I think to generate the IV in the encrypt method rather in the constructor. See http://stackoverflow.com/questions/11821195/use-of-initialization-vector-in-openssl-encrypt to see how to store and restore it. Also, note that mcrypt_create_iv can be very slow if the system has not enough entropy. Personally I use openssl_random_pseudo_bytes. Also, I think there is the iv argument missing in your mcrypt_encrypt/decrypt function calls. – Vincent Pazeller Jan 28 '15 at 09:47

3 Answers3

26

Have you tried the three different second arguments for mcrypt_create_iv(): MCRYPT_RAND (system random number generator), MCRYPT_DEV_RANDOM (read data from /dev/random) and MCRYPT_DEV_URANDOM (read data from /dev/urandom)? Do they offer different consistent speeds? I wonder if it's because /dev/random (the default random source) is running out of collected entropy; the function will block when it does.

Joe Flynn
  • 6,908
  • 6
  • 31
  • 44
WWW
  • 9,734
  • 1
  • 29
  • 33
  • If it's the latter, is there a solution for this or should we just change to `MCRYPT_DEV_URANDOM` ? – Dan Feb 04 '14 at 13:14
  • 2
    @Silver89: just change to `MCRYPT_DEV_URANDOM`. According to Bruce Schneier, neither /dev/random nor /dev/urandom are very robust ( https://www.schneier.com/blog/archives/2013/10/insecurities_in.html ), so you might as well use the one that works. – WWW Feb 04 '14 at 15:06
  • I used `MCRYPT_RAND` which worked. `MCRYPT_DEV_URANDOM` also worked. – Ben Sinclair Feb 25 '14 at 01:48
  • @Crontab At this time `/dev/urandom` and `/dev/random` are robust enough for practical security in applications. Equivocation is not advisable as it may mislead. The Schneirer link is referring to a research paper which suggests strengthening PRNGs according to a new level of robustness which would be secure against sophisticated theoretical attacks. It's proactive research, beyond state of the art at this time. – Mark Fox Nov 03 '14 at 01:24
6

Use MCRYPT_DEV_URANDOM when creating the IV. It's less secure, but won't block if entropy gets too low. MCRYPT_DEV_RANDOM will wait until enough entropy is acquired to be secure.

// PHP < 5.6
$this->iv = mcrypt_create_iv(32, MCRYPT_DEV_URANDOM);

But in more updated versions of PHP, the default has changed and your original code should work.

// PHP >= 5.6
$this->iv = mcrypt_create_iv(32);   // MCRYPT_DEV_URANDOM implied

PHP docs: mcrypt_create_iv (note on $source parameter):

Note that the default value of this parameter was MCRYPT_DEV_RANDOM prior to PHP 5.6.0.

And from Ubuntu Manual:

If you are unsure about whether you should use /dev/random or /dev/urandom, then probably you want to use the latter. As a general rule, /dev/urandom should be used for everything except long-lived GPG/SSL/SSH keys.

rich remer
  • 3,407
  • 2
  • 34
  • 47
  • 1
    This sentiment is echoed and expanded on in the [Ubuntu manual](http://manpages.ubuntu.com/manpages/lucid/man4/random.4.html) — and I quote: "If you are unsure about whether you should use /dev/random or /dev/urandom, then probably you want to use the latter. As a general rule, /dev/urandom should be used for everything except long-lived GPG/SSL/SSH keys." – Mark Fox Nov 03 '14 at 01:45
-1
class Cipher {
    private $securekey, $iv;
    function __construct() {
        $this->securekey = hash('sha256','51(^8k"12cJ[6&cvo3H/!2s02Uh46vuT4l7sc7a@cZ27Q',TRUE);
        $this->iv = isset($_SESSION['sifrem'])?$_SESSION['sifrem']:mcrypt_create_iv(34);
        $_SESSION['sifrem']=$this->iv;
    }
    function encrypt($input) {
        return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->securekey, $input, MCRYPT_MODE_ECB));
    }
    function decrypt($input) {
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB));
    }
    function storeIV() {
        return $this->iv;
    }
}
Littm
  • 4,923
  • 4
  • 30
  • 38
  • 1
    It's never a good idea to reuse an IV, it will have a negative impact on how secure it is. – Sam Jun 07 '14 at 09:57