我已经将身份框架添加到我的WebApi中,并按照此处概述的步骤进行了操作:http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/。所有这些都很好地运作。
我遇到的问题是,我的客户有另一个系统,该API与之集成(以收集数据),并且具有其自己的登录方法。因此,考虑到这一点,我的客户要求我使用CustomPasswordHasher来加密和解密密码。他们想要做的是能够获取密码哈希并将其转换为实际密码,以便他们可以用它来登录旧系统(两个密码/账户将相同)。我知道这非常不正常,但我无法选择。
我的问题是,这样做有多容易?我找到了一些关于如何创建自定义密码哈希程序的主题,但没有显示我如何从哈希密码中获取密码,它们只显示如何进行比较。
目前,我有以下内容:
如果我真的想,我可以这样做:
我遇到的问题是,我的客户有另一个系统,该API与之集成(以收集数据),并且具有其自己的登录方法。因此,考虑到这一点,我的客户要求我使用CustomPasswordHasher来加密和解密密码。他们想要做的是能够获取密码哈希并将其转换为实际密码,以便他们可以用它来登录旧系统(两个密码/账户将相同)。我知道这非常不正常,但我无法选择。
我的问题是,这样做有多容易?我找到了一些关于如何创建自定义密码哈希程序的主题,但没有显示我如何从哈希密码中获取密码,它们只显示如何进行比较。
目前,我有以下内容:
public class PasswordHasher : IPasswordHasher
{
private readonly int _saltSize;
private readonly int _bytesRequired;
private readonly int _iterations;
public PasswordHasher()
{
this._saltSize = 128 / 8;
this._bytesRequired = 32;
this._iterations = 1000;
}
public string HashPassword(string password)
{
// Create our defaults
var array = new byte[1 + this._saltSize + this._bytesRequired];
// Try to hash our password
using (var pbkdf2 = new Rfc2898DeriveBytes(password, this._saltSize, this._iterations))
{
var salt = pbkdf2.Salt;
Buffer.BlockCopy(salt, 0, array, 1, this._saltSize);
var bytes = pbkdf2.GetBytes(this._bytesRequired);
Buffer.BlockCopy(bytes, 0, array, this._saltSize + 1, this._bytesRequired);
}
// Return the password base64 encoded
return Convert.ToBase64String(array);
}
public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
// Throw an error if any of our passwords are null
ThrowIf.ArgumentIsNull(() => hashedPassword, () => providedPassword);
// Get our decoded hash
var decodedHashedPassword = Convert.FromBase64String(hashedPassword);
// If our password length is 0, return an error
if (decodedHashedPassword.Length == 0)
return PasswordVerificationResult.Failed;
var t = decodedHashedPassword[0];
// Do a switch
switch (decodedHashedPassword[0])
{
case 0x00:
return PasswordVerificationResult.Success;
default:
return PasswordVerificationResult.Failed;
}
}
private bool VerifyHashedPassword(byte[] hashedPassword, string password)
{
// If we are not matching the original byte length, then we do not match
if (hashedPassword.Length != 1 + this._saltSize + this._bytesRequired)
return false;
//// Get our salt
//var salt = pbkdf2.Salt;
//Buffer.BlockCopy(salt, 0, array, 1, this._saltSize);
//var bytes = pbkdf2.GetBytes(this._bytesRequired);
//Buffer.BlockCopy(bytes, 0, array, this._saltSize + 1, this._bytesRequired);
return true;
}
}
如果我真的想,我可以这样做:
public class PasswordHasher : IPasswordHasher
{
public string HashPassword(string password)
{
// Do no hashing
return password;
}
public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
// Throw an error if any of our passwords are null
ThrowIf.ArgumentIsNull(() => hashedPassword, () => providedPassword);
// Just check if the two values are the same
if (hashedPassword.Equals(providedPassword))
return PasswordVerificationResult.Success;
// Fallback
return PasswordVerificationResult.Failed;
}
}
但这样做很疯狂,因为所有密码都将以明文的方式存储。肯定有一种方法可以“加密”密码,在进行调用时再进行“解密”吧?