重新使用现有的Microsoft Identity用户表时,密码(哈希)不匹配 [英] Password (hash) doesn't match when re-using existing Microsoft Identity user tables

查看:75
本文介绍了重新使用现有的Microsoft Identity用户表时,密码(哈希)不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个具有 Microsoft Identity 表的现有SQL数据库,该表最初是由ASP.NET Core应用程序生成的.

We have an existing SQL database with Microsoft Identity tables, originally generated by a ASP.NET Core app.

我们还有一个ASP.NET 4应用程序,它也使用Microsoft Identity.

We also have an ASP.NET 4 app, which also uses Microsoft Identity.

我们希望ASP.NET 4应用能够使用与原始.NET Core应用相同的数据库验证登录名.

We'd like the ASP.NET 4 app to be able to validate logins using the same database as the original .NET Core app.

但是,当我们尝试验证密码时,它们不匹配.

However, when we try to validate passwords, they don't match.

我只是猜测.NET Core应用程序生成的密码哈希不能被ASP.NET 4应用程序验证,但是我不确定从何而来. :)

I'm just guessing that the password hashes generated by the .NET Core app cannot be validated by the ASP.NET 4 app, but I'm not sure where to go from here. :)

.NET Core应用程序中没有自定义密码哈希,我正在努力寻找任何可能影响哈希的配置?

There's no custom password hashing in the .NET Core app, and I'm struggling to find any config that might affect hashing?

任何帮助或指针都将不胜感激!

Any help or pointer is greatly appreciated!

编辑:似乎这可能是由Identity V2/V3中的不同哈希算法引起的.不过,不确定如何模仿ASP.NET 4应用程序中的V3哈希算法.

It seems this may be caused by different hashing algorithms in Identity V2/V3. Not sure how to mimic the V3 hashing algorithm in the ASP.NET 4 app, though.

推荐答案

根据位于的文档:一方面,身份使用了不同的哈希算法-也许一种使用了版本2格式,而另一种使用了版本3格式?

At one point, identity used a different hashing algorithm - maybe it's using the version 2 format in one, and the version 3 format in the other?

该类的构造函数接受选项,您可以尝试对其进行调整以获得正确的哈希值?

The constructor of the class takes in options, you can try tweaking that to get the correct hash?

public PasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null)

我在这里找到了Identity v2.0源: https://aspnetidentity.codeplex.com/和git repo: https://git01.codeplex.com/aspnetidentity

I found the Identity v2.0 source here: https://aspnetidentity.codeplex.com/ and git repo: https://git01.codeplex.com/aspnetidentity

浏览源代码,您会发现其哈希方法.

Looking through source, you come across its hashing method.

Crypto.HashPassword.cs

Crypto.HashPassword.cs

public static string HashPassword(string password)
    {
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }

        // Produce a version 0 (see comment above) text hash.
        byte[] salt;
        byte[] subkey;
        using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
        {
            salt = deriveBytes.Salt;
            subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
        }

        var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
        Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
        Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
        return Convert.ToBase64String(outputBytes);
    }

与aspnet身份核心中的v2相比:

Compared to v2 in aspnet identity core:

    private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng)
    {
        const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1; // default for Rfc2898DeriveBytes
        const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes
        const int Pbkdf2SubkeyLength = 256 / 8; // 256 bits
        const int SaltSize = 128 / 8; // 128 bits

        // Produce a version 2 (see comment above) text hash.
        byte[] salt = new byte[SaltSize];
        rng.GetBytes(salt);
        byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength);

        var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
        outputBytes[0] = 0x00; // format marker
        Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
        Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength);
        return outputBytes;
    }

与身份核心v3哈希相比,身份v2哈希和身份核心v2哈希看上去非常相似:

Identity v2 hashing and identity core v2 hashing seem pretty similar, now compared to identity core v3 hash:

    private static byte[] HashPasswordV3(string password, RandomNumberGenerator rng, KeyDerivationPrf prf, int iterCount, int saltSize, int numBytesRequested)
    {
        // Produce a version 3 (see comment above) text hash.
        byte[] salt = new byte[saltSize];
        rng.GetBytes(salt);
        byte[] subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);

        var outputBytes = new byte[13 + salt.Length + subkey.Length];
        outputBytes[0] = 0x01; // format marker
        WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
        WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount);
        WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize);
        Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
        Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
        return outputBytes;
    }

我不会假装理解这些方法中发生的事情,但是从身份v2和身份核心,我们从无参数构造函数过渡到采用配置选项的构造函数. V2使用SHA1,V3使用SHA256.

I'm not going to pretend to understand what's going on in these methods, but from identity v2, and identity core, we went from a parameterless constructor to one that takes in configuration options. V2 uses SHA1, V3 uses SHA256 (among other things).

默认情况下,身份核心似乎将使用V3方法进行哈希处理,而在较早版本的身份中则不存在-这可能是导致您出现问题的原因.

It looks like identity core by default would hash using V3 method, which did not exist in the older version of identity - which would be the cause of your problem.

https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasherOptions.cs

请注意上述来源,默认使用V3.

Note in the above source, V3 is used as the default.

    /// <summary>
    /// Gets or sets the compatibility mode used when hashing passwords.
    /// </summary>
    /// <value>
    /// The compatibility mode used when hashing passwords.
    /// </value>
    /// <remarks>
    /// The default compatibility mode is 'ASP.NET Identity version 3'.
    /// </remarks>
    public PasswordHasherCompatibilityMode CompatibilityMode { get; set; } = PasswordHasherCompatibilityMode.IdentityV3;

不幸的是,这似乎意味着您在身份核心中散列的密码无法在较旧的身份版本中进行相同的散列,因为未实现该较旧的方法.也许您可以模仿在v3中创建的内容来创建自己的游戏?

Unfortunately, that looks like it means your passwords that were hashed in identity core cannot be hashed the same in an older version of identity, as that older method was not implemented. Perhaps you could create your own mimicking what was done in v3?

这篇关于重新使用现有的Microsoft Identity用户表时,密码(哈希)不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆