C# compare hashed password (Pbkdf2) - c#

I am developing an authentication in .Net Core.
I have api to create a user with login and password.
I hashed the password, but I don't find any way to compare the hashed password, with the new input of the user.
I used the hash method given by microsoft :
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing?view=aspnetcore-3.1
// generate a 128-bit salt using a secure PRNG
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
/// hashed will be stored in the DataBase as password
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
When the user do a login, he send a login and a password.
I have no idea how to compare this password, with the hashed password from the database ?
If I hash the password again, it will be a different hash, so that doesn't help
Any suggestion ?
I am surprised that I don't find answers about this :(
Thanks !

UserInout : plaintext ==> Send to authentication service,
create account: generate salt, hash given plaintext-password with salt, store in account infos
authenticate: read hash from account info in your database, hash the given plaintext password with the read salt and compare that hash with the hash in your database. That is the simplest way of authentication.
Be sure to always use the individual hash that was created for each account, otherwise the hash will always be different and authentication will fail.

Related

Verify C# HMACSHA256 in PHP

I have a user's data and the passwords are hashed with HMAC-SHA256 and encrypted with AES (Umbraco CMS with uCommerce). I need to import that password so the old user could log in to the new website (using WordPress and WooCommerce). I have a secret key (salt) from the previous website and I intend to make the old password 'readable' and verified in WordPress as the password would re-hashed again using WordPress hashing algorithm when the user login.
I read the hash_hmac function in PHP and does it can be applied in WordPress authentication alongside WordPress's own hashing algorithm (MD5)?
Thank you.
Update
Previous title: HMAC-SHA256 hashed password in WordPress from another CMS
I have a website using Umbraco CMS (written in C#) and want to replicate their hashing algorithm in WordPress (PHP) to migrate the old password hashed in the previous website. I try to replicate the hash that I get from the DB:
Password: likeasmyname
Hashed: X9gbVOGeHJPbifmaVCCYcg==qXwkrnY3HxAPB0bjnBxw3IAe3n0yX5q7Dk/I+MTAiX4=
That is the generated hash from the password "likeasmyname" using HMACSHA256 with salt in 128bit length. Based on their algorithm, they hash the password and prepend the salt before stored the DB. Source: GitHub
I infer that the X9gbVOGeHJPbifmaVCCYcg== is the salt and the rest is the password qXwkrnY3HxAPB0bjnBxw3IAe3n0yX5q7Dk/I+MTAiX4=
I try this:
<?
$password= "likeasmyname";
$passwordUtf16 = mb_convert_encoding($password, 'UTF-16LE');
$hashFull = "X9gbVOGeHJPbifmaVCCYcg==qXwkrnY3HxAPB0bjnBxw3IAe3n0yX5q7Dk/I+MTAiX4=";
$hashSalt = "X9gbVOGeHJPbifmaVCCYcg==";
$hashPassword = "qXwkrnY3HxAPB0bjnBxw3IAe3n0yX5q7Dk/I+MTAiX4=";
$hashSaltDecoded = base64_decode($hashSalt);
$hashAlgo = hash_hmac('sha256', $hashSaltDecoded . $passwordUtf16, $hashSaltDecoded, true);
echo $hashAlgo;
?>
Result:
Result: lg2AaF0ogBpop02CgdmeM3efENQwagXWpFhW7zG0Jpk=
Expected: qXwkrnY3HxAPB0bjnBxw3IAe3n0yX5q7Dk/I+MTAiX4=
What am I missing?

Storing and comparing multiple passwords with ServiceStack

I'm attempting to create a password expiration function in my application. Passwords are already set up as well as authentication and changing passwords. Now I want to prompt the user to change their password after x amount of time.
When the user goes to change their password and my Angular frontend makes that request I want my C# Service Stack API to compare the given new password with the current password and the password before that to check for duplication.
I'm not worried about slight variations. If the user submits the same password but with one extra character for example, that's fine. I want to be an simple as possible to start.
The passwords are stored in a MS SQL Server in two columns Salt varchar(8000) and PasswordHash varchar(8000). I've got everything set up I'm just very confused on how to compare the hashed password with the string provided by the User. Then save the old password in a new hashed column. I've been searching the web and SOF for three days now and I haven't found anything. Any guidance would be greatly appreciated.
Following on #Fildor comment, you'll need to create an audit history of password changes containing the hashes of existing passwords. From ServiceStack v5+ ServiceStack switched to use the same PBKDF2 password hashing algorithm ASP.NET Identity v3 uses which stores the password hash + salt + iterations + algorithm version in a single PasswordHash field on UserAuth table, so your password audit history table only needs a single column to store the existing password hash.
The password hashing algorithm is available from the IPasswordHasher dependency, which you can use in your Service implementation like:
public IPasswordHasher PasswordHasher { get; set; }
public object Any(AllowPassword request)
{
var passwordHashes = MyRepo.GetExistingUserPasswords(GetSession().UserAuthId);
foreach (var passwordHash in passwordHashes)
{
if (PasswordHasher.VerifyPassword(passwordHash, request.Password, out var neeedsRehash)
throw new ArgumentException("Can't use existing password", nameof(request.Password));
}
return new AllowPasswordResponse();
}

Hash password in xamarin to match database hashed password

Im very new to xamarin, and currently I need to hash my user password before sending it to the api to verify as sending the plain text over the web is a security risk.
In my web application i use Microsoft.AspNet.Identity to hashpasswords and save them to the database
public UserManager<IdentityUser> UserManager { get; private set; }
string strPasswordHash = UserManager.PasswordHasher.HashPassword(viewModel.Password);
Im trying to get the same hash algorithm as this but im unsuccessful. So i would like to know if this is possible to get the same hash in xamarin somehow
So when hashing the following test password "TestP#ssw0rd" i would get "AKtowbhuu47Dn4Pk8r4SM4zKo6P7N/N27afp6aDBL4sroWzOiXucrSG6kiHrjU2Ayw==" so how would I in xamarin hash the same password send it to my api which uses the Microsoft.AspNet.Identity.PasswordHasher() to verify the 2 hashed passwords.
use using System.Security.Cryptography
public string MD5Hash(string input)
{
System.Security.Cryptography.SHA512Managed sha512 = new System.Security.Cryptography.SHA512Managed();
Byte[] EncryptedSHA512 = sha512.ComputeHash(System.Text.Encoding.UTF8.GetBytes(string.Concat(input, securityCode)));
sha512.Clear();
return Convert.ToBase64String(EncryptedSHA512);
}
Input is your plaintext and securityCode is salting password to create secured hashcode,
you have to define and assign securitycode

Encrypt passwords existing in Database sql windowsForms

I have a database of logins and passwords. I wouldn't like that anyone who has access to the database can see everybody's password. How can I encrypt the passwords in the database?
In other words, I want the fields pwd (password) to be encrypted in the database but it is automatically decrypted when I enter it in the LoginForm.
I have found a method that encrypt the strings input but it doesn't solve my issue.
static string Encrypt(string value)
{
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
UTF8Encoding utf8 = new UTF8Encoding();
byte[] data = md5.ComputeHash(utf8.GetBytes(value));
return Convert.ToBase64String(data);
}
}
private void BtnEncrypt_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtPass.text))
{
MessageBox.Show("Please enter your password !");
}
texResult.Text=Encrypt(txtPass.Text);
}
Please, can somebody help me.
Thanks in advance.
You can Encrypt your password using your Encrypt function and store the Encrypted password in your database.
But Decrypting the password, is not a good option. Password Encryption should be one way.
To check whether the password is available in your database, you can Encrypt the password entered by user by using the same Encrypt function, then match that Encrypted password to encrypted password you have in your database.
Thanks
It is easy to muddle encryption with hashing. What you are asking about is encryption - encryption lets you turn your password into an apparently random sequence of characters which can then be decrypted to get the original password back. What you should be using (and some have suggested) is hashing.
There are lots of examples of how to do encryption/decryption on the net, just search. This is the first one that came up for me: http://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C Tempting as it is to copy and paste the code from there, I won't because this isn't what you should be doing. For storing user passwords in a database it is much better to use password hashing (with salt) than to store encrypted passwords. Why? because then if your system is hacked it is impossible for an attacker to recover people's passwords - all your accounts might still be compromised but given that people often use the same password for more than one system you won't be compromising your users.
A hash is a one way function, so you can't get the original password back. When someone wants to login you simply generate a hash and then compare it with the one you have stored in the database. If you want to read more about this and why you should be using it then this is a good start: https://crackstation.net/hashing-security.htm If you would like to jump in and get some working code then have a look at Hash and salt passwords in C#.
You can use any complex cryptography technique to encrypt a password and send the password key to be saved in database for corresponding user.
Now when the client tries to login and enters password, sends it to server.
From the server you can again convert the login details and compute the hash and finally send to a stored procedure to compare. If the two strings match, you return true else false as for authentication.
using System.Security.Cryptography;
...
...
...
private const string _alg = "HmacSHA256";
private const string _salt = "rz8LuOtFBXphj9WQfvFh"; // Generated at https://www.random.org/strings
public static string GenerateToken(string username, string password)
{
string hash = string.Join(":", new string[] { username, password });
using (HMAC hmac = HMACSHA256.Create(_alg))
{
hmac.Key = Encoding.UTF8.GetBytes(GetHashedPassword(password));
hmac.ComputeHash(Encoding.UTF8.GetBytes(hash));
hash = Convert.ToBase64String(hmac.Hash);
}
return Convert.ToBase64String(Encoding.UTF8.GetBytes(hash));
}
public static string GetHashedPassword(string password)
{
string key = string.Join(":", new string[] { password, _salt });
using (HMAC hmac = HMACSHA256.Create(_alg))
{
// Hash the key.
hmac.Key = Encoding.UTF8.GetBytes(_salt);
hmac.ComputeHash(Encoding.UTF8.GetBytes(key));
return Convert.ToBase64String(hmac.Hash);
}
}
MD5 is not secure anymore.
When a user register to use your application, hash the password with SHA512 bit with salt. You can find like PWDTK nuget package which we can easily use. Password is what we don't need to know what it means but just plays a secure role. Like some person commented above, when the user try to log-in after user registration, just encrypt the user's input(password) and compare it with that registered in SQL database. Password must be one-way.
After the login result comes up success or fail, the role of password is finished.
As of Winform cases, you need to deeply consider to secure the connectionstring to connect to SQL database. One possible option might be WCF middleware between Winform application and SQL database.
And for last but very importantly, you must use SSL for secure communication.
It seems you might consider these at later stages.

C# HMAC Implementation

I want my application to encrypt a user password, and at one time password will be decrypted to be sent to the server for authentication. A friend advise me to use HMAC. I wrote the following code in C#:
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] key = encoding.GetBytes("secret");
HMACSHA256 myhmacsha256 = new HMACSHA256(key);
byte[] hashValue = myhmacsha256.ComputeHash(encoding.GetBytes("text"));
string resultSTR = Convert.ToBase64String(hashValue);
myhmacsha256.Clear();
How to decode the password (resultSTR, in this case)?
An HMAC (Hashed Message Authentication Code) is not encryption, it's hash function (in this case SHA-256) plus some secret key. It's lossy, there is no way to derive the plaintext from the HMAC.
If you want to encrypt some secret data, you should consider using the ProtectedData class instead. More infom including sample code at http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx

Categories

Resources