Update password change the hash in database - hash

I'm using Bcrypt to encode the password when the user resets it. The encode is working but in the database the encode changes and the password is not valid, so the user can no longer login.
$options = [ 'cost' => 13 ];
$encodedPassword = password_hash($newPassword, PASSWORD_BCRYPT, $options);
$em->getConnection()->executeUpdate( 'UPDATE User SET password = ? WHERE id = ?',array($encodedPassword, $user->getId()));
$em->flush();
the column option in the database is a varchar(70) with character set utf8 and collation utf8_unicode-ci.
I'm checking here https://bcrypt.online/#bcrypt-hash-validator-verifier that the hash is valid with the result of $encodedPassword but when I check it for what it is in the database I get the result "The plain text does not match the supplied hash."
EDIT
I notice the problem is not with the hash. The problem is the function is running twice and the second time it hashes a null reference and inserting in the database, and that's why the user cannot login.
The problem is that I don't know why the render method ends calling the function __destruct() in the classes.php files multiple times and somehow it executes again the function.

Related

How to choose column in sql select using variable in Qt

I am writing a function that will take a string variable and work with a column with the name of this variable, but i can't figure out how to write variable in select
I tried this where test is QString variable with value company, but it didnt work like if there was company without variable
QString test = "company";
QSqlQuery password = db->exec("SELECT password FROM '"+test+"'");
Worked with deleted '' of the variable.
QSqlQuery password = db->exec("SELECT password FROM "+test+"");

How to remove configuration parameter

In Postgres it is possible to create your own configuration parameters, something like a "cookie" that persists for duration of either session or transaction.
This is done like that:
SELECT set_config(setting_name, new_value, is_local)
or
SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }
Local is supposed to persist only for duration of transaction, but it does affect configuration parameter even after transaction - instead of said parameter being unrecognized, it will be now set to empty string.
Question
How to make said parameter unrecognized again, without reconnecting?
This does not work:
SELECT set_config('settings.myapp.value', null, true);
RESET settings.myapp.value;
This will not return NULL, instead it gives empty string:
SELECT current_setting('settings.myapp.value', true);
I can of course work around this, but I would like to know if I can somehow revert state of configuration parameter back to what it was before "transaction only" change.
SELECT nullif(current_setting('settings.myapp.value', true), '');
You cannot do that.
If you create a new parameter, it is created as a “placeholder” parameter.
If you later load a module that defines that parameter, it will be converted to a “real” parameter on the fly.
But there is no way to delete a parameter during the lifetime of a database session.

Drupal save global variables

I make a form in drupal to store data (for annonymous user) so when the form is validate i would like to save it to access it from all page but that does not work outside this function the variable is NULL
can you help me or have you another method to proceed ?
function myform_form_submit($form, &$form_state) {
....
$GLOBALS ['info'] = $info;
}
When a Drupal form is evaluated, it executes any code, including database changes. But then it redirects the user to a new page, which discards the PHP session, including $GLOBALS, among other things.
The more Drupally way is to use persistent variables, which are stored in the "variables" database table.
The variable_set function can be used here. So replace
### $GLOBALS['info'] = $info ### replace with:
variable_set('mymodule_info', $info);
and then when you access it, instead of using $GLOBALS, just use
$info = variable_get('mymodule_info', NULL);
You can use any name to specify the variable. I add NULL as a second parameter to variable_get in case the value isn't present in the database.
If the data is associated with a particular user, you might need to do something like
global $user;
variable_set('mymodule_info_uid_' . $user->uid, $info);
and then to retrieve the data use
global $user;
$info = variable_get('mymodule_info_uid_' . $user->uid, NULL);
EDIT: Ah, now I see you're dealing with anonymous users. In that case, PHP can identify anonymous users for you by giving a session id that can be used in the same way:
variable_set('mymodule_info_session_' . session_id(), $info);
variable_get('mymodule_info_session_' . session_id(), NULL);
This should be persistent for an anonymous user's browsing session.
The issue with this approach is that you'll need to come up with some way of clearing these out. You'll probably need to store a timestamp in the $info variable and have a cron job to delete expired entries from the variable table.

Password hashing (crackstation.net)

I have a question regarding password hashing. I found a great tutorial on http://crackstation.net/hashing-security.htm. This is how I create a hash from the password using this code:
$hashed_password = create_hash(form_password);
The problem with this code is that it creates a different hash for the same password every time. I guess it's because of adding a random salt to the password:
function create_hash($password)
{
// format: algorithm:iterations:salt:hash
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" .
base64_encode(pbkdf2(
PBKDF2_HASH_ALGORITHM,
$password,
$salt,
PBKDF2_ITERATIONS,
PBKDF2_HASH_BYTES,
true
));
}
So due to this, I cannot compare the hash created from the password typed by the user at the login with the hash retrieved from the database, because that hash will never be the same with the one stored in the database. The only way I see that it can be done is to store the salt in another column, or am I wrong?
A thing also annoys me. The format of the hast is e.g. sha256:1000:u9p+OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wficCU0EG. A hacker obviously knows this form of hash so the algorythm that created this hash is clear for him. Let's suppose the database has been compromised and thousands of these hash codes were revealed. Doesn't having this form of hash code raise security issues? I guess a simple OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wfic would be better because it reveals nothing about the encryption mechanism.
Read this link to Wikipedia here
It explains more about the use of a random salt. The key information there is that the random salt is stored in the same database as the hashed password. It is only created randomly a few time, when the user creates or changes their password. It is used whenever authentication is required.
Leaving the info about which algorithm it used to create the password hash leaves you the option of changing the algorithm at some time in the future without interrupting your users. If you decide up upgrade the hash algorithm you wait until a user logs in. At that point you have their password in plain text. Once you authenticate against the old algorithm, you rehash and store the new hash in their database row. It may take months or years for all users to log in but once they have they will accrue the benefits of better hashing. So you would then send out an email asking them to login and read your special news about better security (and as a side effect, improve their hashed password).
Here is an interesting discussion of password hashing StackOverflow:Passwords Storage Hash ...
The reason two hashes of the same password don't match for you is because the result of create_hash() includes the salt, which is randomly generated.
To get the same hash, you have to provide the salt as you validate. The code CrackStation.net provides makes this super simple - just store the result of create_hash() in your database, exactly as-is. To confirm a user entered the correct password, use
validate_password('provided-password','hash-from-database');
This will return a boolean of whether the password was correct. Using this method is better than writing your own, because it is specifically designed to prevent certain hints at what the correct password might be based on the time it takes to return an answer. This is a minor weakness, but better to avoid it anyway, especially since the provided function takes care of it for you.
The provided functions give you a solid implementation, so don't mess with it too much. The hash includes those extra details - sha256:1000 - in order to allow future changes to your hashing without affecting the ability of existing users to login; it will simply use the method provided in the hash, no matter what the current method is.
As far as showing a potential attacker how the hash was created: the format does show everything about how, but this doesn't matter very much at all. An attacker can easily figure out the method used from one or two known password:hash pairs. Far more important than this is using a good algorithm. The goal is to make it difficult to impossible to crack the password even with all the details, as security by obscurity is poor security.
Finally, just to reiterate, you do not need to store the salt in a separate column, just leave the big 70-80 character chunk it returns alone as your hash and let the functions take care of everything for you - anything else is a waste of time and resources
To add a bit more to the excellent accepted answer:
The point about salting the hash is to make it impossible for someone to come along with a huge pile of pre-encrypted hashes and try them one by one. Even with the salt in your database, they'd have to hash every possible dictionary entry against that salt to successfully match a hash. And the salt needs to be different every time to prevent duplicate entries (they hack one password, they have that same password that other users have entered).
As for not being able to compare the login hash to the stored hash, that is on purpose: you use a validation function to check the login password against the stored password, not a string comparison function.
Store the salt then add the salt to the password then turn it into a hash then store it.
Then to compare the passwords you retrieve the salt and add it to he password, convert it into a hash and then compare the two hashes.
(python example, the indentation is messed up when I copied the code from my code)
def Createpassword():
import random
import hashlib
username = input("type your username")
newpassword = input("type your new password? ")
#adds some salt
b = random.randint(1, 2000000000000)
randomsalt = str(b)
saltedpassword = (newpassword + randomsalt)
#hashes the newpassword
saltedpassword = saltedpassword.encode('utf-8')
h = hashlib.sha256(saltedpassword)
finsh = h.hexdigest()
#creates file names
saltname = username + "salt.txt"
username = username + ".txt"
#saves the hashedpassword and the salt
text_file = open(username, "w")
text_file.write(finsh)
text_file.close()
text_file = open(saltname, "w")
text_file.write(randomsalt)
text_file.close()
print("your new password has been saved")
def EnterPassword():
trys = 0
while (trys < 3):
username = input("type your username: ")
#takes password input
password = input("type your password: ")
#gets file names
saltname = username + "salt.txt"
username = username + ".txt"
#opens salt file
text_file = open(saltname, "r")
salt1 = text_file.read(50)
text_file.close()
#opens the hashed passwords file
text_file = open(username, "r")
correctpassword = text_file.read(500)
text_file.close()
#adds the salt to the password input
saltedpassword = password + salt1
#hashes the saltedpassword
saltedpassword = saltedpassword.encode('utf-8')
m = hashlib.sha256(saltedpassword)
hashedpassword = m.hexdigest()
#compears hashed passwords
if hashedpassword != correctpassword:
trys += 1
print("your password or username is incorrect")
if trys == 3:
print("you have been locked out for using to many failed trys")
if hashedpassword == correctpassword:
print ("Password Correct ")
#done give access
trys = 0
break
(I'm new to programming so feel free to correct me)

Hashing and salting in a PDO prepared statement

Can someone show me the proper format to use for hashing and salting in a PDO prepared statement? I'm switching from php and trying to get this to work in a simple INSERT statement before worrying about the more complex functions, and nothing that I've seen online has worked.
In php I was doing this: '".sha1($salt + $_POST['password'])."'
I've tried:
$password = '123456';
$hash = hash('sha1', $password);
$pass1 = hash('sha1', $salt . $hash . $password);
$salt is defined in config.php, referenced correctly, and works properly in php insert statements.
EDIT -
This is the INSERT statement that I'm using:
$stmt = $conn->prepare('INSERT INTO customer_info (fname...) VALUES(:fname...)');
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->execute();
Most database systems do not have decent passwort hash functions available, so you cannot generate the hash value with SQL. I'm not sure what you mean with "switching from PHP", but let the development language generate the hash, not the database system.
The salt should be different for every password, a global salt cannot fulfill it's purpose. Your "salt" is actually a key (or pepper), it is always the same. A salt has to be stored (plaintext) together with the hash-value, you need it to compare the stored hash with the hash of the entered password.
PHP 5.5 will have it's own functions password_hash() and password_verify() ready, to simplify generating BCrypt password hashes. I strongly recommend to use this excellent api, or it's compatibility pack for earlier PHP versions. Then i would invite you to read more about correct password storing with salt and pepper in this tutorial.
Edit:
Normally an insert with PDO looks something like this:
$password = $_POST['password'];
$hashedPassword = sha1($password . $salt);
$sql = 'INSERT INTO user (name, passwordhash) VALUES (?, ?)';
$sth = $pdo->prepare($sql);
$sth->execute(array('Jack Cornfield', $hashedPassword));
Of course your statement will look different, but i don't know your table and fields. In the example, the generation of the hash is done in pure PHP, and the resulting $hash is added parameterized to the sql statement with placeholders.