Secure Token Process
I am currently in the mist of developing a website using PHP and MYSQL. It is a private website therefore registrations must be allowed using emails. In simple terms if a new user has to be registered, the administrator has to go into the system and add an email address to be registered.
What I want to do 开发者_如何学运维is to create a token or a pass value when this does happen.
Here are the steps:
- Administrator adds an email to the system
- A unique token value is created (e.g. 1234567890)
- The token value is then sent to the users email
- the user goes on the link provided and enters his email and the token value
- If Success - User is allowed to register
- If Fail! - Token is regenerated and send again to that email address
What I really want to know is what would be the best practice to create a token and how can we ensure to create a unique token every time an email is registered.
For further security can I ensure that each token only live for a couple of hours. But would this prevent unauthorized access into the system, or this is a bad idea for securing my website?
My thoughts of creating a unique token: Use hashing algorithms that use SALT so the results cannot be predicted or decrypted (Problems with MD5)
Any help or a lead towards the right direction would be greatfull.
I like this method of generating a cryptographically secure pseudo-random number generator or (CSPRNG) for PHP. It was written by Scott:
<?php
function crypto_rand_secure($min, $max) {
$range = $max - $min;
if ($range < 0) return $min; // not so random...
$log = log($range, 2);
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
$rnd = $rnd & $filter; // discard irrelevant bits
} while ($rnd >= $range);
return $min + $rnd;
}
function getToken($length=32){
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
for($i=0;$i<$length;$i++){
$token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
}
return $token;
}
?>
In terms of adding a timeout, I recommend taking care of this in the database. Add a column that is called like registration_timeout and then use mysql's addtime() function to set this colmn to the current time stamp + however long you want the timeout to be.
Also keep in mind that temporary email accounts are trivial to use (http://www.mailinator.com , http://www.guerrillamail.com, ect...), so asking for someone to register an email account doesn't mean anything. Further more a user account could end up on http://www.bugmenot.com .
精彩评论