http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/
所有这一切都很好.
我遇到的问题是,我的客户端有另一个系统,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,array,1,this._saltSize); var bytes = pbkdf2.GetBytes(this._bytesrequired); Buffer.Blockcopy(bytes,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,this._saltSize); //var bytes = pbkdf2.GetBytes(this._bytesrequired); //Buffer.Blockcopy(bytes,this._bytesrequired); return true; }}
如果我真的想,我可以这样做:
public class PasswordHasher : IPasswordHasher{ public string HashPassword(string password) { // Do no hashing return password; } public PasswordVerificationResult VerifyHashedPassword(string hashedPassword,() => provIDedPassword); // Just check if the two values are the same if (hashedPassword.Equals(provIDedPassword)) return PasswordVerificationResult.Success; // Fallback return PasswordVerificationResult.Failed; }}
但那会很疯狂,因为所有密码都会以纯文本形式存储.当然有一种方法可以“加密”密码并在我打电话时“解密”它?
解决方法 所以,我尽量保证安全.这就是我所做的.我创建了一个新的提供者:
public class AdvancedEncryptionStandardProvIDer{ // Private propertIEs private Readonly ICryptotransform _encryptor,_decryptor; private UTF8EnCoding _encoder; /// <summary> /// Default constructor /// </summary> /// <param name="key">Our shared key</param> /// <param name="secret">Our secret</param> public AdvancedEncryptionStandardProvIDer(string key,string secret) { // Create our encoder this._encoder = new UTF8EnCoding(); // Get our bytes var _key = _encoder.GetBytes(key); var _secret = _encoder.GetBytes(secret); // Create our encryptor and decryptor var managedAlgorithm = new RijndaelManaged(); managedAlgorithm.BlockSize = 128; managedAlgorithm.KeySize = 128; this._encryptor = managedAlgorithm.CreateEncryptor(_key,_secret); this._decryptor = managedAlgorithm.CreateDecryptor(_key,_secret); } /// <summary> /// Encrypt a string /// </summary> /// <param name="unencrypted">The un-encrypted string</param> /// <returns></returns> public string Encrypt(string unencrypted) { return Convert.ToBase64String(Encrypt(this._encoder.GetBytes(unencrypted))); } /// <summary> /// Decrypt a string /// </summary> /// <param name="encrypted">The encrypted string</param> /// <returns></returns> public string Decrypt(string encrypted) { return this._encoder.GetString(Decrypt(Convert.FromBase64String(encrypted))); } /// <summary> /// Encrypt some bytes /// </summary> /// <param name="buffer">The bytes to encrypt</param> /// <returns></returns> public byte[] Encrypt(byte[] buffer) { return transform(buffer,this._encryptor); } /// <summary> /// Decrypt some bytes /// </summary> /// <param name="buffer">The bytes to decrypt</param> /// <returns></returns> public byte[] Decrypt(byte[] buffer) { return transform(buffer,this._decryptor); } /// <summary> /// Writes bytes to memory /// </summary> /// <param name="buffer">The bytes</param> /// <param name="transform"></param> /// <returns></returns> protected byte[] transform(byte[] buffer,ICryptotransform transform) { // Create our memory stream var stream = new MemoryStream(); // Write our bytes to the stream using (var cs = new CryptoStream(stream,transform,CryptoStreamMode.Write)) { cs.Write(buffer,buffer.Length); } // Retrun the stream as an array return stream.ToArray(); }}
然后我的PasswordHasher,我改为:
public class PasswordHasher : IPasswordHasher{ // Private propertIEs private Readonly AdvancedEncryptionStandardProvIDer _provIDer; public PasswordHasher(AdvancedEncryptionStandardProvIDer provIDer) { this._provIDer = provIDer; } public string HashPassword(string password) { // Do no hashing return this._provIDer.Encrypt(password); } public PasswordVerificationResult VerifyHashedPassword(string hashedPassword,() => provIDedPassword); // Just check if the two values are the same if (hashedPassword.Equals(this.HashPassword(provIDedPassword))) return PasswordVerificationResult.Success; // Fallback return PasswordVerificationResult.Failed; }}
要使用此PasswordHasher,您可以像这样调用它:
var passwordHasher = new PasswordHasher(new AdvancedEncryptionStandardProvIDer(ConfigurationManager.AppSettings["as:key"],ConfigurationManager.AppSettings["as:secret"]));
这似乎满足了我的条件.如果有安全隐患请告诉我!
总结以上是内存溢出为你收集整理的c# – 身份框架和自定义密码哈希全部内容,希望文章能够帮你解决c# – 身份框架和自定义密码哈希所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)