c# – 身份框架和自定义密码哈希

c# – 身份框架和自定义密码哈希,第1张

概述我已将标识框架添加到WebApi中,并按照此处概述的步骤 *** 作: http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/ 所有这一切都很好. 我遇到的问题是,我的客户端有另一个系统,API与其集成(收集数据)并拥有自己的登录方法.因此,考虑到这一点,我的客户要求我使用 我已将标识框架添加到WebAPI中,并按照此处概述的步骤 *** 作:

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# – 身份框架和自定义密码哈希所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1232212.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存