PHP - Should I Use Salt?
I honestly don't think salt is necessary with my system. I currently use:
$password = md5(sha1(md5(sha1($_POST['password'])))); Is this good enough when it comes to storing a password, encrypted? Similar TutorialsOk this is my script so far: Code: [Select] class User { function generateHash($password, &$saluti=null) { define('SALT_LENGTH', 15); $key = '!@#$%^&*()_+=-{}][;";/?<>.,'; if ($saluti=="") { $saluti = substr(hash('sha512', uniqid(rand(), true).$key.microtime()), 0, SALT_LENGTH); } else { $saluti = substr($saluti, 0, SALT_LENGTH); } return hash('sha512', $saluti . $key . $password); } function validate_user($username,$password) { $mysql = new Database(); $hashedPassword = generateHash($password,''); $ensure_credentials = $mysql->verify_username_and_password($username,$hashedPassword); if($ensure_credentials) { $_SESSION['auth'] == "yes"; header("Location: index.php"); } else return "That was not the correct username or password."; } } It gives me this error: Quote [05-Feb-2012 17:14:59] PHP Fatal error: Call to undefined function generatehash() in /home1/elvonica/public_html/scripts/classes/user.php on line 24 Can anyone help me solve this? which would be secured to use friends? or could we use both together? show some usage example please Salting passwords... How can you update the salting without getting all the users to change their password? Is the salting set in stone once created? Hi guys, Iv been reading into password salting and im struggling to understand its purpose. From what iv read you can basic salt a password by doing the following: $salt = "randomtext"; $password = "apple"; $password = md5($password.$salt); I was wondering though, if a hacker is able to crack the md5, wont they see the password and the salt? Example: a hacker cracks the md5 to reveal applerandomtext. From applerandomtext it wont be hard for them to work out that the password is apple. So doesn't that make the idea of salting pointless? I'm still trying to figure out why I should use salt. If the bad guy knows a name and tries something like brute force shoving passwords into the log-in form until one worked how would salt help stop that? If a bad guy, God forbid, gets hold of the user names and passwords like they did phpbb(?) forums several years ago how would salt stop that? I know I may be beating this issue to death but if I have salt in the users table assigned to a user and his password now equals $stored_password = sha1($salt.$password) does this really doesn't matter? Because if the bad guy knows the user name and uses brute force or has a list of passwords from the users table that he has gotten some way. All he has to do is type in the user name and password and salt will be added automatically. I was wondering how most people use salt or what is the order of the steps to use salt? Does the script take the new password then encrypt it then add salt and in encrypt it again, are they just added together and then encrypted or is it a combination of something like that? And I guess the de-encrypting would be the reverse. Not looking for code just the big picture. Thanks S Just a quick question. I have heard a few people say that they store a specific (maybe random) salt string in the same row as the user that is generated when the user account is created or password is changed. But I thought one of the reasons people use hashing is so if someone managed to get hold of the database they couldn't decipher the password (like a simple md5'd string). But putting the salt string next to the username surely gives the attacker a major push in the right direction? I am not claiming to know anything, I'm just asking because I'm trying to find the best practice (Or at least a good tried and tested one). I like the idea of having a salt in a php config file, because that would mean an attacker would actually have to get your files, and if they had got that far then your pretty much screwed anyway. When a User changes his/her Email Address, should I generate a new Salt and Hash? (I am re-using the code I used for a Password Reset, and during that I generated a new Salt and Hash for security. I guess it can't hurt...) Thanks, Debbie I am currently testing a small hash idea, for say database encryption for passwords. Basically what I want to know is if this is a good or not the best method for encryption... Code: [Select] <?php $us_password = 'drowssap'; // User-Submitted Password; $salt = '))!&8d*34d763!(('; //The salt $dbs_password = '3750221c513902ff76f4ec7ffed5fa4385d2599d'; // Sha1 hash for "drowssap"+Salt; if($us_password == sha1($us_password.$salt)){ //Some other code for success here } else { //Failure code here } ?> So basically, this is an abstract example of what I'm doing... Is it any good, or what could be improved? I've also used DB-Stored salts unique to each user, so even if someone used rainbow tables ( even after failure on my part for letting them get the hash... ), and multiple users had the same password, they would only crack one, rather than all of them, since the hashes would be different due to the different salts. I'm incorporating a dynamic salt into my user system, but I'm not sure how to store the salt itself. The password is hashed and added to the database, but wouldn't you need to store the salt as plain text in the database in order to verify the login later? Also, I've read that using both a dynamic and static salt is good practice. If this is the case, is the static salt simply defined within the PHP? Or is there another method to storing it? Thanks for the help Hi Guys, I wonder If I can call on this forums help once again. I am trying to add salt to my md5 password hash. However I think I am getting the syntax slightly wrong as it is not working properly. It works in the fact that when someone logs in and they have a 1 next to the member type it will direct them to the teachers page . However if no values are entered into the log in form and someone clicks log in it will still direct them to the students page when I thought it would direct them to log in failed. The code for the log in form is: Code: [Select] //Sanitize the POST values $login = clean($_POST['login']); $password = clean($_POST['password']); $salt = "salt"; $EncryptedPassword=md5($password, $salt); //Create query $qry="SELECT * FROM users WHERE username='$login' AND password='$EncryptedPassword'"; $result=mysql_query($qry); //Check whether the query was successful or not if($result) { if(mysql_num_rows($result) == 1) { //Login Successful session_regenerate_id(); $member = mysql_fetch_assoc($result); $_SESSION['SESS_MEMBER_ID'] = $member['id']; $_SESSION['SESS_FIRST_NAME'] = $member['FirstName']; $_SESSION['SESS_LAST_NAME'] = $member['LastName']; $_SESSION['SESS_LAST_NAME'] = $member['Member_Type']; session_write_close(); } //if the member has an id equal to 0 send them to the member page if($member['Member_Type'] == 0){ header("Location: Student-Page.php"); //if the member has an id equal to 1 send them to the admin page } elseif($member['Member_Type'] == 1){ header("Location: Teachers-Page.php"); } // regardless of the outcome, we need to exit, so it can be done once after both checks exit(); } else { //Login failed header("location: login-failed.php"); exit(); } In case you need it the code for the registration form where the password is originally salted upon creation is: Code: [Select] <?php //Start session session_start(); //Include database connection details require_once('config.php'); //Connect to mysql server $link = mysql_connect(DB_HOST, DB_USER ,DB_PASSWORD); if(!$link) { die('Failed to connect to server: ' . mysql_error()); } //Select database $db = mysql_select_db(DB_DATABASE); if(!$db) { die("Unable to select database"); } //Function to sanitize values received from the form. Prevents SQL injection function clean($str) { $str = @trim($str); if(get_magic_quotes_gpc()) { $str = stripslashes($str); } return mysql_real_escape_string($str); } //Sanitize the POST values $username = clean($_POST['username']); $FirstName = clean($_POST['FirstName']); $LastName = clean($_POST['LastName']); $Member_Type = clean($_POST['Member_Type']); $password = clean($_POST['password']); $Cpassword = clean($_POST['Cpassword']); $salt = "salt"; $EncryptedPassword = md5($password,$salt); //Check for duplicate login ID if($username != '') { $qry = "SELECT * FROM users WHERE username='$username'"; $result = mysql_query($qry); if($result) { if(mysql_num_rows($result) > 0) { } @mysql_free_result($result); } else { //die("query failed"); } } //Create INSERT query $qry = "INSERT INTO users(username, password, FirstName, LastName, Member_Type) VALUES('$username','$EncryptedPassword','$FirstName','$LastName','$Member_Type')"; $result = @mysql_query($qry); //Check whether the query was successful or not if($result) { header("location: register-success.php"); exit(); }else { die("Query Failed"); } ?> If someone could take a look and point me in the right direction. Also if there are any other mistakes let me know I would be very grateful. Thanks in advance. Edd I have this little snippet of code that runs when a user updates their password: fetch_user_salt_new(): Code: [Select] function fetch_user_salt_new($length = 5) { $salt_a = ''; for ($i = 0; $i < $length; $i++) { $salt_a .= chr(vbrand(33, 126)); } return $salt_a; } Code: [Select] $salt = fetch_user_salt_new(); $salt_processed = mysql_real_escape_string($salt); Now, occasionally when a user changes their password (or anything that inserts the salt into the database, such as registration), the salt length stored in the database becomes 6 or 7 instead of 5. As in, 99% of salts are only 5 digits long, but some salts are longer... The longer salts normally have odd components, such as \', \", or \\ leading to salts increasing by 1 or 2 digits in length. My idea is that mysql_real_escape_string() is putting a \ in front of quotes which is not what I intended when adding that piece of code in. By adding mysql_real_escape_string() in, I intended for quotes (' or ") to not be factors affecting the Query. Prior to instituting mysql_real_escape_string(), a ' or " would close the query and mess up the insertion of the salt. (Original Topic: http://www.phpfreaks.com/forums/index.php?topic=356368.0 ) It seemed to work but not doesn't Any help is very appreciated, Mark Knowing that it has to be set once upon script installation and never changed, what is the most common way to handle this in redistributable scripts? Should I add a salt value in the config file and ask the user to set it, or should I generate a random value and write it to a file, or should I take a different approach entirely? <?php function cryptPass($input, $rounds = 9){ $salt = ""; $saltChars = array_merge(range('A','Z'), range('a','z'), range(0,9)); for($i = 0; $i < 22; $i++){ $salt .= $saltChars[array_rand($saltChars)]; } return crypt($input, sprintf('$2y$%02d$', $rounds) . $salt); } echo $inputPass = "password2"; echo $pass = "password"; $hashedPass = cryptPass($pass); echo $hashedPass; if(crypt($inputPass, $hashedPass) == $hashedPass){ echo "<br /><h1>Password is a match = log user in</h1>"; }else{ echo "<br />Password does not match = do not log in"; } ?>My PHP version 5.2 When I run above code I am getting the password match answer. I should have get error message. Can anyone advise me . Thank you. Hi, I'm trying to add encryption to a signup for a college assignment, but find that after adding the sha1 and salt encryption the code does not work. The code worked before adding the encryption. Since adding the encryption I've also adding the corresponding fields for username and password into the sql database and double checked, and triple checked all the php, html form and MySQL tables and fields, but don't see any thing wrong. Can anybody else see any immediate problems with the code snippet below? If so, can you please let me know? session_start(); $salt = 'The sky is blue and all the trees are green'; $data = array_map('mysql_escape_string', $_POST); $password = sha1($data['password'].$salt); $query = " INSERT INTO customers ( first_name, last_name, address, mobile, email, username, password ) VALUES ( '{$data['first_name']}', '{$data['last_name']}', '{$data['address']}', '{$data['mobile']}', '{$data['email']}' '{$data['username']}', '$password' ) "; if(mysql_query($query)) { echo 'Your login details have been saved.'; } else { echo 'Your login details have not been saved.<br>'; echo 'Please try again later.'; } Thanks. Hi
I'm having a strange error with this code and i get it working properly
function CheckLoginInDB($username,$password) { if(!$this->DBLogin()) { $this->HandleError("Erro na ligação à Base de Dados!"); return false; } $username = $this->SanitizeForSQL($username); $nresult = mysql_query("SELECT * FROM utilizador WHERE utilizador = '$username'", $this->connection) or die(mysql_error()); // check for result $no_of_rows = mysql_num_rows($nresult); if ($no_of_rows > 0) { $nresult = mysql_fetch_array($nresult); $salt = $nresult['salt']; echo $salt; $encrypted_password = $nresult['password']; $hash = $this->checkhashSSHA($salt, $password); echo $hash; } $qry = "Select idutilizador, nome, email from utilizador where utilizador='$username' and password='$hash'"; $result = mysql_query($qry,$this->connection); if(!$result || mysql_num_rows($result) <= 0) { $this->HandleError("Erro: Utilizador ou password errados"); return false; } $row = mysql_fetch_assoc($result); $_SESSION['idutilizador'] = $row['idutilizador']; $_SESSION['name_of_user'] = $row['nome']; $_SESSION['email_of_user'] = $row['email']; return true; }This is my table Field Type Collation Null Key Default Extra Privileges Comment Hi, I am limbo with this one. What I have makes sense to me, but I know I'm missing something or doing something wrong I have been able to hash passwords with salt by new people registering to my site by doing this: if(!$error) { $alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz1234567890"; $rand = str_shuffle($alpha); $salt = substr($rand,0,40); $hashed_password = sha1($salt . $_POST['password']); $query = "INSERT INTO `cysticUsers` ( `FirstName`, `LastName`, `Email`, `Password`, `salt`, `RelationshipToCF`, `State`, `Gender`, `Birthday`, `Status` )VALUES( '" . mysql_real_escape_string($_POST['firstName']) . "', '" . mysql_real_escape_string($_POST['lastName']) . "', '" . mysql_real_escape_string($_POST['email']) . "', '" . $hashed_password . "', '" . $salt . "', '" . mysql_real_escape_string($_POST['RelationToCF']) . "', '" . mysql_real_escape_string($_POST['State']) . "', '" . mysql_real_escape_string($_POST['sex']) . "', '" . mysql_real_escape_string($_POST['DateOfBirth_Year'] . "-" . $_POST['DateOfBirth_Month'] . "-" . $_POST['DateOfBirth_Day']) . "', 'pending' )"; mysql_query($query, $connection); I have been able to to update EXISTING users passwords by doing this: $query = "SELECT * FROM `cysticUsers`"; $request = mysql_query($query,$connection); while($result = mysql_fetch_array($request)) { $alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz1234567890"; $rand = str_shuffle($alpha); $salt = substr($rand,0,40); $hashed_password = sha1($salt . $result['Password']); $user = $result['id']; $query2 = "UPDATE `cysticUsers` SET `salt` = '$salt' WHERE `id` = '$user'"; $request2 = mysql_query($query2,$connection) or die(mysql_error()); $query3 = "UPDATE `cysticUsers` SET `encrypted_passwords` = '$hashed_password' WHERE `id` = '$user'"; $request3 = mysql_query($query3,$connection) or die(mysql_error()); } Now, I want to be able to SIGN BACK IN with the existing password and I am failing miserably by doing this: $query = "SELECT `salt`,`id`,`email`,`password` FROM `cysticUsers` WHERE `Email` = '" . $email . "' AND `Password` = '" . $password . "' && `Status` = 'active' LIMIT 1"; $request = mysql_query($query,$connection) or die(mysql_error()); $email = mysql_real_escape_string($_POST['email']); $password = mysql_real_escape_string($_POST['password']); if(@mysql_num_rows($request)) { $row = mysql_fetch_assoc($request); if (sha1($row['salt'] . $_POST['password']) === $row['Password']) { $_SESSION['CLIFE']['AUTH'] = true; $_SESSION['CLIFE']['ID'] = $result['id']; // UPDATE LAST ACTIVITY FOR USER $query = "UPDATE `cysticUsers` SET `LastActivity` = '" . date("Y-m-d") . " " . date("g:i:s") . "' WHERE `id` = '" . mysql_real_escape_string($_SESSION['CLIFE']['ID']) . "' LIMIT 1"; mysql_query($query,$connection); if(!empty($_POST['return'])) { header("Location: " . $_POST['return']); }else{ header("Location: CysticLife-Dashboard.php?id=" . $_SESSION['CLIFE']['ID']); } } }else{ $_SESSION['CLIFE']['AUTH'] = false; $_SESSION['CLIFE']['ID'] = false; } } I've been scouring resources and am stuck on this. I have a deadline to meet that I am behind on. Needless to say I'm pulling my hair out and some help with this would be GREATLY appreciated. Thank you in advance! I've never done salting before. Usually just use md5, but the rainbow tables kinda scare me. Anyway, I read up a little on salting and does this look right?..right meaning effective Also, my salt string, is it case sensitive when I crypt it? <?php if (isset($_POST['submit'])) { $salt = "someStringThatonlYYiWillKnow!"; $username = stripslashes(mysql_real_escape_string(strtolower($_POST['username']))); $password = stripslashes(mysql_real_escape_string(md5($_POST['password']))); $ePass = crypt($password,$salt); $query = mysql_query("SELECT active,username,password FROM usernames WHERE username = '" . $username . "' AND password = '" . $ePass . "'") or die(mysql_error()); $num = mysql_num_rows($query); if ($num == 1) { $result = mysql_fetch_array($query); if ($result['active'] == 'yes') { $_SESSION['user']['username'] = $result['username']; $_SESSION['user']['authed'] = true; header("Location: main.php"); } else { $error = " <div class=\"notification information\"> <div>We located your account, however, it has not been activated by an admin yet.</div> </div>"; } } else { $error = " <div class=\"notification error\"> <div>Invalid Username / Password.</div> </div>"; } } ?> |