Membership.ValidateUser不使用Pbkdf2Hash来处理散列密码

时间:2015-02-10 05:16:37

标签: c# asp.net asp.net-mvc asp.net-membership

我正在使用存储过程将用户插入成员资格表

EXEC @error_code = Aspnet_membership_createuser  
            @ApplicationName = @ApplicationName,  
            @UserName = @user_name,  
            @Password = @Password,  
            @PasswordSalt = @PasswordSalt,  
            @Email = @user_name,  
            @PasswordQuestion = NULL,  
            @PasswordAnswer = NULL,  
            @IsApproved = 1,  
            @CurrentTimeUtc = @CurrentTime,  
            @CreateDate = @CurrentTime,  
            @PasswordFormat = 1,  
            @UserId = @UserId OUTPUT  

我正在使用以下代码

创建密码和密码salt
PBKDF2Implementation hash = new PBKDF2Implementation();
string passwordSalt;
model.Password = hash.CreateHash(model.Password, out passwordSalt);
_repo.CreateUser(model.Name, model.Email, model.Password, passwordSalt);

和PBKDF2Implementation类如下所示

public class PBKDF2Implementation
{
    private const int MinSaltSize = 32;
    private const int MaxSaltSize = 64;

    public static string GetRandomKeyAsBase64String()
    {
        return Convert.ToBase64String(GetRandomKeyAsByteArray());
    }

    private static byte[] GetRandomKeyAsByteArray()
    {
        var random = new Random();
        var saltSize = random.Next(MinSaltSize, MaxSaltSize);
        var saltBytes = new byte[saltSize];
        var rng = new RNGCryptoServiceProvider();
        rng.GetNonZeroBytes(saltBytes);
        return saltBytes;
    }


    public string CreateHash(string plainText, out string salt)
    {
        var saltBytes = GetRandomKeyAsByteArray();
        salt = Convert.ToBase64String(saltBytes);
        var pwdGen = new Rfc2898DeriveBytes(plainText, saltBytes, 1000);
        byte[] key = pwdGen.GetBytes(32);
        return Convert.ToBase64String(key);
    }

    public bool CompareHash(string plainText, string hashValue, string salt)
    {
        if (String.IsNullOrEmpty(salt)) throw new ArgumentNullException("salt");
        var saltBytes = Convert.FromBase64String(salt);
        var pwdGen = new Rfc2898DeriveBytes(plainText, saltBytes, 1000);
        var key = pwdGen.GetBytes(32);
        var generatedPassword = Convert.ToBase64String(key);
        return generatedPassword == hashValue;
    }
}

现在用硬件密码和密码盐

创建用户

enter image description here

是的,用户已获批准但未被锁定。

当我尝试使用MembershipProvider的验证用户验证他时出现问题。它不起作用,总是返回false。

我的webconfig中有以下配置。

<membership defaultProvider="AdminSqlMembershipProvider" userIsOnlineTimeWindow="15" hashAlgorithmType="CustomPbkdf2Hash">
  <providers>
    <clear />
    <add name="AdminSqlMembershipProvider" 
         type="ABC.Service.Security.AdminSqlMembershipProvider"
         connectionStringName="ABCAdManagementAspNetConnection"
         applicationName="ABC Internal Web Application"
         enablePasswordRetrieval="false"
         enablePasswordReset="true"
         requiresQuestionAndAnswer="false"
         requiresUniqueEmail="true"
         passwordFormat="Hashed"
         description="Retrieves membership data from Global Master" />
  </providers>
</membership>

我的global.asax有这个

System.Security.Cryptography.CryptoConfig.AddAlgorithm(typeof (Pbkdf2Hash.Pbkdf2Hash), "CustomPbkdf2Hash");

我的Pdkdf2Hash类看起来像这样

public class Pbkdf2Hash : KeyedHashAlgorithm
{
    private const int kHashBytes = 32;
    const int minSaltSize = 32;
    const int maxSaltSize = 64;

    private System.IO.MemoryStream _ms;

    public int WorkFactor { get; set; }

    public Pbkdf2Hash()
    {
        this.WorkFactor = 1000;
        //SqlMemberShipProvider will adjust the length of its internal generated salt size while calling computehash 
        // but while adding new user uses a fixed size salt value.
        var random = new Random();
        var saltSize = random.Next(minSaltSize, maxSaltSize);
        this.Key = new byte[0x20]; 
    }

    public override int HashSize
    {
        get
        {
            return kHashBytes * 8;
        }
    }

    public override void Initialize()
    {
        _ms = null;
    }

    protected override void HashCore(byte[] array, int ibStart, int cbSize)
    {
        (_ms = _ms ?? new System.IO.MemoryStream()).Write(array, ibStart, cbSize);
    }

    protected override byte[] HashFinal()
    {
        _ms.Flush();

        var arr = _ms.ToArray();

        _ms = null;
        return new Rfc2898DeriveBytes(arr, this.Key, this.WorkFactor).GetBytes(kHashBytes);
    }

}

我在这里做错了什么,membership .validateuser就不行了。

0 个答案:

没有答案