c# – 身份框架和自定义密码哈希
我已将标识框架添加到WebApi中,并按照此处概述的步骤操作:
http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/ 所有这一切都很好. 我的问题是,这有多容易? 目前我有这个: 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"])); 这似乎满足了我的条件.如果有安全隐患请告诉我! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |