73 lines
2.7 KiB
C#
73 lines
2.7 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace SharpUI.Source.Common.Util.Encryption
|
|
{
|
|
/// <summary>
|
|
/// Password encryption utilities.
|
|
/// </summary>
|
|
public class PasswordUtil : IPasswordUtil {
|
|
private const short ByteSize = 128;
|
|
private const int AlgIterations = 1000;
|
|
|
|
private readonly IConvertProxy _convertProxy;
|
|
|
|
public PasswordUtil()
|
|
{
|
|
_convertProxy = new ConvertProxy();
|
|
}
|
|
|
|
public PasswordUtil(IConvertProxy convertProxy)
|
|
{
|
|
_convertProxy = convertProxy;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Given the raw password in form of a character sequence, return a hashed password.
|
|
/// </summary>
|
|
/// <param name="password">Raw password</param>
|
|
/// <returns>Hashed password</returns>
|
|
/// <exception cref="PasswordEncryptException">Exception thrown if password is an empty string.</exception>
|
|
public string PasswordHash(string password) {
|
|
string pwdHash;
|
|
var salt = new byte[ByteSize];
|
|
using (var provider = new RNGCryptoServiceProvider()) {
|
|
provider.GetBytes(salt);
|
|
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, AlgIterations);
|
|
var hash = pbkdf2.GetBytes(ByteSize);
|
|
var hashBytes = new byte[ByteSize*2];
|
|
Array.Copy(salt, 0, hashBytes, 0, ByteSize);
|
|
Array.Copy(hash, 0, hashBytes, ByteSize, ByteSize);
|
|
pwdHash = _convertProxy.ToBase64String(hashBytes);
|
|
}
|
|
|
|
if (pwdHash.Trim().Length == 0) {
|
|
throw new PasswordEncryptException("ERROR: The PasswordHash() extension is trying to return empty hash value!");
|
|
}
|
|
|
|
return pwdHash;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verify if the password matches the hashed password.
|
|
/// </summary>
|
|
/// <param name="password">Raw password</param>
|
|
/// <param name="hashedPassword">Hashed password</param>
|
|
/// <returns>True if password matches the hashed password, otherwise false.</returns>
|
|
public bool IsPasswordValid(string password, string hashedPassword) {
|
|
var valid = true;
|
|
var bytes = Convert.FromBase64String(hashedPassword);
|
|
var salt = new byte[ByteSize];
|
|
Array.Copy(bytes, 0, salt, 0, ByteSize);
|
|
|
|
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, AlgIterations);
|
|
var hash = pbkdf2.GetBytes(ByteSize);
|
|
|
|
for (var i = 0; i < ByteSize; i++) {
|
|
valid &= bytes[i + ByteSize] == hash[i];
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
}
|
|
} |