我们有一个内置于 .NET Framework 4.5 版本的 ASP.NET Web 应用程序。目前正在生产中,此应用程序使用 SHA1 加密算法。该算法设置在应用程序的 web.config 文件的“MachineKey”标签中。此应用程序使用 ASP.Net 成员资格概念来维护登录凭据。

由于 SHA1 算法即将降级,因此我们希望将应用程序从 SHA1 更新为 SHA2。为此,我们在应用程序的 web.config 文件的“MachineKey”标签中设置了“HMACSHA256”。

使用上述设置将我们的应用程序升级到 SHA2 后,我们预计旧用户的密码(使用 SHA1 加密并已存在于成员(member)数据库中)将无法使用 SHA2 算法。但它允许较老的用户无需修改先前加密的密码即可登录。

问题 1:在应用程序的 web.config 文件的“MachineKey”标签中所做的更改是否足够/推荐用于此迁移?

问题 2:由于我们仍然可以使用以前加密的密码登录应用程序,因此成员(member)数据库是否真的使用了 web.config 文件中设置的 SHA2 加密?或者我们需要添加一些额外的设置来启用成员(member)数据库级别的 SHA2 加密?请指教。

请建议是否有在成员(member)数据库级别启用 SHA2 加密的最佳方法。

最佳答案

我不知道是否可以通过 Membership 处理这样的迁移,而不强制用户进行密码重置过程。

但是您可以通过同时将 Membership 迁移到 Asp.Net Identity 来做到这一点:Asp.Net Identity 具有扩展点,允许您处理“回退”密码签名匹配以支持旧签名。那时,您仍然在内存中保留未散列的登录名和密码,然后您可以顺便将签名转换为新格式。

所有这些都在 blog 后面用细节和代码进行了解释,包括 SQL 迁移,我只是在下面的代码中添加的注释中稍微解释了一下。

这是实现此目的的主要类:



然后,在您的用户管理器中:

public class IdentityUserManager : UserManager<IdentityUser>
{
    public IdentityUserManager(IUserStore<IdentityUser> store)
        : base(store)
    {
        PasswordHasher = new BackCompatPasswordHasher();
    }
}

在我的实际代码库中,我添加了一些处理重新散列的内容,但不幸的是,没有说明原因。也许这是原始实现者的一些多余代码,或者确实需要它。我没有调查过,所以这里是 IdentityUserManager 中的附加代码:
    private ConcurrentDictionary<string, string> UserRehashed =
        new ConcurrentDictionary<string, string>();

    private bool CanRehash(IdentityUser user)
    {
        return UserRehashed.TryAdd(user.Id, user.Id);
    }

    protected async override Task<bool> VerifyPasswordAsync(
        IUserPasswordStore<IdentityUser, string> store, IdentityUser user,
        string password)
    {
        var hash = await store.GetPasswordHashAsync(user).ConfigureAwait(false);
        var verifPassRes = PasswordHasher.VerifyHashedPassword(hash, password);
        if (verifPassRes == PasswordVerificationResult.SuccessRehashNeeded &&
            // avoid rehash loop.
            CanRehash(user))
        {
            var chPassRes = await this.ChangePasswordAsync(user.Id,
                password, password).ConfigureAwait(false);
            if (!chPassRes.Succeeded)
            {
                // throw or log, whatever.
            }
        }

        return verifPassRes != PasswordVerificationResult.Failed;
    }

关于c# - 从 SHA1 迁移到 SHA2 ASP.net 4.5,C#,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34928787/

10-11 00:24