One reason why mcrypt responds slowly

Summary

Slow responses from mcrypt scripts, particularly under parallel requests, often stem from `mcrypt_create_iv()` defaulting to `/dev/random` for IV generation. This blocking random number generator relies on system entropy and can cause processes to hang when the entropy pool is depleted. To mitigate this performance issue, explicitly specify `MCRYPT_DEV_URANDOM` as the source for `mcrypt_create_iv()`. While `/dev/urandom` provides non-blocking random numbers and improves throughput, developers should note its theoretical predictability compared to `/dev/random` for critical security applications.

This morning one colleague came over and talked about one script which used mcrypt responded very slowly, the server configurations are fine. But the reason for the slowness is unknown.

Here is one script which reproduces the issue:

<?php
$dmcryptText = "dummy";
$key = "foobar";
$size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
 
$iv = mcrypt_create_iv($size); //Take care
 
$m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
var_dump($m);

When 20 requests of this script are sent to the server in parallel, the response time of Apache server increases rapidly.

The reason for the slowness is illustrated below.

If no argument is specified for mcrypt_create_iv(), it will use /dev/random(on Linux) by default as a random number generator. The problem of /dev/random is that its random pool depends on the system interrupts, when there is not enough system interrupts, it cannot generate enough random numbers, then the process which tries to get the random numbers will wait and hang. Let's look at a simple example.

$ dd if=/dev/random bs=1024k count=1

When the system is busy, the output speed will be very slow, sometimes there will be pause.

The solution is using /dev/urandom instead of /dev/random, /dev/urandom is also a random number generator but it doesn't depend on system interrupts to generate the random numbers.

<?php
$dmcryptText = "dummy";
$key = "foobar";
$size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
 
$iv = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM); //Take care
 
$m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
var_dump($m);

The reason why using /dev/random as default is that /dev/urandom is predictable in theory, so generally /dev/random is safer than /dev/urandom. See /dev/random for details.

Reference : http://www.laruence.com/2012/09/24/2810.html

PHP SOLUTION SLOW MCRYPT RESPONSE

  RELATED

  COMMENTS

8
Anonymous
Apr 5, 2016 at 2:14 am

Thanks it worked for me :)

Ke Pi
Apr 5, 2016 at 4:25 am

Glad to hear about this

Anonymous
Jun 23, 2016 at 4:24 am

After 2 nights of banging my head against the wall, this solved my problem, thank you !

Ke Pi
Jun 23, 2016 at 8:45 am

Glad to hear about this

Anonymous
Oct 18, 2016 at 10:27 am

Thanks! It was really helpful. It help me to understand my problem and solved! Thanks so much :D

Arvids
Oct 18, 2016 at 11:23 am

Using mcrypt these days in any shape or form is irresponsible at best. It is abandoned for more than 10 years. has glaring issues and is in the process of being dropped completely. Switch to alternatives.

Ke Pi
Oct 18, 2016 at 11:37 am

For alternatives, you are referring to OpenSSL?

Anonymous
Oct 18, 2016 at 2:11 pm

Why are you using Blowfish in ECB mode?