is there any default implementation for password history? i'm trying to implement that feature on my project with identity so i have added password history table which contain password hashes. when user change password usermanager generate hash for password.
var passwordHash = _userManager.PasswordHasher.HashPassword(user, newPassword);
if this hash does not inserted in password history table it allow to change password otherwise return error
but the problem is each time when generating hash for the specific password it generate random hashes which cannot be compare also
var passwordHash = _userManager.PasswordHasher.HashPassword(user, newPassword);
hash differ from
_userManager.ResetPasswordAsync(user, request.Token, password);
generated password hash.
May be i'm trying to do this in wrong way. what was the mistake i have done implementing password history?
thanks
Different hashes every time - it's how default implementation IPasswordHasher works. Look at this answer for more details: https://stackoverflow.com/a/20622428/6104621.
So, for your implementation password history, you can either implement IPasswordHasher or just verify a new password with all stored passwords hashes using method
PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword);
Just for example:
var passAlreadyExist = user.UserHistory
.Select(h => h.PasswordHash)
.Distinct()
.Any(hash =>
{
var res = manager.PasswordHasher.VerifyHashedPassword(user, hash, password);
return res == PasswordVerificationResult.Success;
});
where UserHistory - it's custom table with some user info like password, email, name...
Related
I am trying to use the Pimcore password datatype. It is working fine and the password is stored as encrypted data.
Now I need to check the correct username and password. I could not match the encrypted password. I want to get the username and password using an API request. If the username and the password is correct then return value.
The password is hashed before it is stored to the database. Have a look at the password class within this path:
pimcore/models/DataObject/ClassDefinition/Data/Password.php
If you want to compare the hashed password within the database then use the functions of the password datatype. The password to compare also has to be hashed.
Have a closer look on the functions calculateHash() and verifyPassword() within the class. You should be able to compare passwords by using those functions.
Here is an example :
$user = User::GetByEmail($email, ['limit' => 1, 'unpublished' => false]);
$classDefinition = ClassDefinition::getById(User::classId());
/** #var \Pimcore\Model\DataObject\ClassDefinition\Data\Password $passwordFieldDefinition */
$passwordFieldDefinition = $classDefinition->getFieldDefinition('password');
$verified = $passwordFieldDefinition->verifyPassword($password, $user, false);
I have completed login functionality using Auth middleware where is used a Bcrypt encryption method. Login functionality is works fine. But we need to handle set password functionality with having old password need to validate. But everytime Bcrypt method change the password string so the previous store bcrypt string of password in table is not match with the manually enter password in the set password form. So how to validate old password field if it will not match with existing saved passoword in the table.
$credentials = request(['email', 'password']);
$user=Auth::attempt($credentials);
You are using Laravel so you should use Hash in order to deal with passwords.
Here is all you need to know about it: https://laravel.com/docs/6.x/hashing#basic-usage
In short you can create and verify the passwords in following ways:
Create hashed password to store in DB:
$hashedPassword = Hash::make($request->password);
Verify against existing password
if (Hash::check('entered-password-by-user', $hashedPassword)) {
// The passwords match...
}
Of course dont forget to include Hash facade: use Illuminate\Support\Facades\Hash;
md5 is ancient and very vulnerable way to go if you want to hash your passwords with it. It is HIGHLY DISCOURAGED!
I found a blog post about BCrypt and I'am not sure what is the Benefit ob adding the hard-coded Salt "^Y8~JJ" to the password?
The 'hashToStoreInDatabase' containing the salt and the crypted password, but not the hard-coded salt 'Y8~JJ'. So, if somebody steal the database it's useless for the hacker to generate an own rainbowtable with the salt (containing in the database) and the hashed password, because they never get the hard-coded salt 'Y8~JJ'.
(I knew that is already safety to save the salt and passwordhash togheter, because a rainbowtable is expencive to generate)
Is this using of BCrypt recommended?
Quote from: https://www.codeproject.com/articles/475262/useplusbcryptplustoplushashplusyourpluspasswords
private void SetPassword(string user, string userPassword)
{
string pwdToHash = userPassword + "^Y8~JJ"; // ^Y8~JJ is my hard-coded salt
string hashToStoreInDatabase = BCrypt.HashPassword(pwdToHash, BCrypt.GenerateSalt());
using (SqlConnection sqlConn = new System.Data.SqlClient.SqlConnection(...)
{
sqlConn.Open();
SqlCommand cmSql = sqlConn.CreateCommand();
cmSql.CommandText = "UPDATE LOGINS SET PASSWORD=#parm1 WHERE USERNAME=#parm2";
cmSql.Parameters.Add("#parm1", SqlDbType.Char);
cmSql.Parameters.Add("#parm2", SqlDbType.VarChar);
cmSql.Parameters["#parm1"].Value = hashToStoreInDatabase;
cmSql.Parameters["#parm2"].Value = user;
cmSql.ExecuteNonQuery();
}
}
private bool DoesPasswordMatch(string hashedPwdFromDatabase, string userEnteredPassword)
{
return BCrypt.CheckPassword(userEnteredPassword + "^Y8~JJ", hashedPwdFromDatabase);
}
It is actually called pepper. The salt is stored in DB, but pepper is stored somewhere else then DB.
The Wikipedia states as;
A pepper performs a comparable role to a salt, but while a salt is not secret (merely unique) and can be stored alongside the hashed output, a pepper is secret and must not be stored with the output. The hash and salt are usually stored in a database, but a pepper must be stored separately (e.g. in a configuration file) to prevent it from being obtained by the attacker in case of a database breach.
When the database hacked, the attacker cannot access the pepper, as a result, password search would be impossible even for weak passwords.
In short, yes recommended.
However, Bcrypt is old. One should use Argon2 as the winner of the password hashing competition.
I'm looking for a simple way to generate passwords that will only work once for a limited amount of time, e.g. 1 day, 1 week, 1 month. This has to be implemented in an application that has no connectivity so a server isn't possible. The use case is something like:
1. Generate password for a specific date and length of time.
2. Send to user (email, phone, etc).
3. User enters in application.
4. Application is enabled for a specific time.
5. Password cannot be reused, even on another PC.
I'm assuming the only way to do this is to generate passwords that only work between a specific set of dates. Can anyone recommend an algorithm that can do this? It doesn't have to be incredibly secure, and I know you can crack this by resetting the time on the PC!
Thanks.
I know I'm late but I'll provide my advice anyway in case someone else who needs it found their way here.
To prevent it being used on another PC, you could probably use the MAC address or hardware address. However, this is subject to the network hardware being still available when checking the password. Please make sure you use the hardware address of the machine where the password will be checked.
private string GetBase64Mac()
{
System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
if (interfaces.Length == 0)
{
System.Net.NetworkInformation.PhysicalAddress add = interfaces[0].GetPhysicalAddress();
if (add != null)
return System.Convert.ToBase64String(add.GetAddressBytes());
}
return "";
}
To limit it by some expiry date simply use the text string of the expiry date.
private string GetExpiryDate(DateTime expiryDate)
{
return expiryDate.ToString("yyyyMMdd");
}
Simply use a hash function to hash the combine expiry date, hardware address and a secret key. Prefix or suffix the hash output with the expiry date.
private void GeneratePassword(string prefix)
{
string secretKey = "MySecretKey";
System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
byte[] preHash = System.Text.Encoding.UTF32.GetBytes(prefix + secretKey + GetBase64Mac());
byte[] hash = sha.ComputeHash(preHash);
string password = prefix + System.Convert.ToBase64String(hash);
return password;
}
In the case above, i prefix the hash with the expiry date. So, when we check the password, we simply extract the expiry date from the password, use the same function to generate the same password. If the generated password match the provided password, then you have green light.
private void TestPassword()
{
int duration = 15; // in days
string prefix = GetExpiryDate(DateTime.Today.AddDays(duration));
string generated = GeneratePassword(prefix);
// Positive test
string testPrefix = generated.Substring(0, 8);
string testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return false;
// Negative test
generated[2] = '2';
generated[12] = 'b';
testPrefix = generated.Substring(0, 8);
testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return true;
return false;
}
Sample output password:
20110318k3X3GEDvP0LkBN6zCrkijIE+sNc=
If you can't get the hardware address, then simply use the customer's name. It won't prevent the password from being used in multiple machines, but it will ensure that the same person is using it.
Your application should have a attribute like validity for the password something like this
username password_hash validity_from Validity_end
xyz a73839$56 11-Nov-2010 12-Nov-2010
and then in your application you can validate that your password has expired or not
Generate passwords by any method you'd like (a word list, random letters, etc). Put them into some data structure, like an associative array, where you can associate a date with each password. Then you consult this data structure in the program that hands out passwords to give one out with the proper expiration date. The client program has the same list of passwords and dates, so when it gets a password, it just looks up the associated expiration date there.
The PasswordHasher takes in a generic TUser and then takes the user's object for hashing and verifying, something like this:
var result = hash.VerifyHashedPassword(user, HashedPassword, Password);
string HashedPassword = hash.HashPassword(user, Password);
So I am assuming the user data is used to hash the password and then to verify. But doesn't this mean I need to rehash the password? If so, wouldn't that mean each time the user changes any of his account info he also needs to re-enter his password or is there a way around it where I can rehash it without asking the user for his password?