This is a long question to read so Question in short is, is it secure to depend on PHP’s rand function for generating first time password?
In my free time, I was just thinking of a logic to make very difficult custom password generator (only digits), a feature that I might need in my next project.
First thing that come in mind is PHP’s rand() method. I tried few test around rand method to test its random behaviour. As general, it first come to mind that generating more than one random number and doing some operation on that will make random number more difficult to guess. I was surprised to see that average of random numbers is very near to its half using following program:
$minAvg=$maxAvg=50;
for($i=1;$i<=1000;$i++){
//Random average
$sum=0;
for($j=0;$j<1000;$j++){
$sum=$sum+rand(1,100);
}
$avg=$sum/1000;
///
if($avg<$minAvg){
$minAvg=$avg;
}
if($avg>$maxAvg){
$maxAvg=$avg;
}
if($i%100==0)
{
echo "at i=$i, Min Avg = $minAvg and Max Avg = $maxAvg <br/>";
}
}
One output of above code was:
at i=100, Min Avg = 47.174 and Max Avg = 53.003
at i=200, Min Avg = 47.174 and Max Avg = 53.003
at i=300, Min Avg = 47.174 and Max Avg = 53.003
at i=400, Min Avg = 47.174 and Max Avg = 53.003
at i=500, Min Avg = 47.174 and Max Avg = 53.192
at i=600, Min Avg = 47.174 and Max Avg = 53.192
at i=700, Min Avg = 47.174 and Max Avg = 53.192
at i=800, Min Avg = 47.174 and Max Avg = 53.192
at i=900, Min Avg = 47.174 and Max Avg = 53.204
at i=1000, Min Avg = 47.174 and Max Avg = 53.204
I run above code at least 50 times but even after 1000 iteration, average always remain between 47.xx to 53.xx (for random numbers between 1 & 100)
Although this result doesn’t tells a lot as generally average of few numbers must come near middle but I didn’t expected same behaviour for random numbers. I feel it show PHP’s rand() use some fixed algorithm which generate numbers in a given pattern. As far as I understand, this is only justified reason for average to remain near middle.
Till now I was using random numbers frequently to generate first time password (which was forcefully changed during first login). However now I’m little worried if it is safe to use random numbers for generating first time passwords of sites which involve financial transaction and sensitive info like credit card numbers (although encrypted). Is there any possibility for hackers (not amateur but professional hackers) to break such passwords with easy? Most important, is there any algorithm to detect (or at least estimate) next random number.
Edit
Well to make it more sensible, user will be registered offline for example like opening bank account and printed first time password will be sent through Post, not by email. So password must remain under 10 characters which rules out any encryption.
rand()is not a cryptographic-strength RNG, but it does not matter here.All you need from a random password is that it should be unpredictable enough that random guessing is not feasible. This property has much more to do with the length and allowed character pool of the password than it has to do with
rand().Moreover, the best line of defense against brute forcing is introducing a deliberate delay between login attempts. If you do this and have “reasonably random” passwords there is absolutely no way you are going to get brute forced.
And finally, under the hood
rand()is implemented using a linear congruential generator. Unless the server is going to spend most of its time generating passwords (highly doubtful) you can get “better” randomness by switching tomt_rand(), which is an implementation of Mersenne Twister (it’s still not crypto-strength).