ASP.NET DefaultMembershipProvider的哈希函数中是否存在错误?

我正在迁移我的旧版ASP.NET webforms应用程序,以开始使用ASP.NET内置的DefaultMembershipProvider。 我的旧homebrewn authenticationmodule用于存储SHA256密码哈希值。 我认为’升级’到DefaultMembershipProvider,它也在SQL DB中存储哈希值,这意味着我也可以迁移这些哈希值,因此可以为当前用户提供无痛的升级(因此他们不必重置密码)。

现在,这并没有按计划进行(很明显!)我开始研究DefaultMembershipProvider的来源(更具体地说,就在这里: https : //github.com/wyxy2005/bluceNet/tree/master/ System.Web.Providers )和我来了以下函数:

private string EncodePassword(string pass, int passwordFormat, string salt) { if (passwordFormat == 0) { return pass; } byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Convert.FromBase64String(salt); byte[] inArray = null; if (passwordFormat == 1) { HashAlgorithm hashAlgorithm = this.GetHashAlgorithm(); KeyedHashAlgorithm algorithm2 = hashAlgorithm as KeyedHashAlgorithm; if (algorithm2 != null) { if (algorithm2.Key.Length == src.Length) { algorithm2.Key = src; } else if (algorithm2.Key.Length < src.Length) { byte[] dst = new byte[algorithm2.Key.Length]; Buffer.BlockCopy(src, 0, dst, 0, dst.Length); algorithm2.Key = dst; } else { int num2; byte[] buffer5 = new byte[algorithm2.Key.Length]; for (int i = 0; i < buffer5.Length; i += num2) { num2 = Math.Min(src.Length, buffer5.Length - i); Buffer.BlockCopy(src, 0, buffer5, i, num2); } algorithm2.Key = buffer5; } inArray = algorithm2.ComputeHash(bytes); } else { byte[] buffer6 = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, buffer6, 0, src.Length); Buffer.BlockCopy(bytes, 0, buffer6, src.Length, bytes.Length); inArray = hashAlgorithm.ComputeHash(buffer6); } } else { byte[] buffer7 = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, buffer7, 0, src.Length); Buffer.BlockCopy(bytes, 0, buffer7, src.Length, bytes.Length); inArray = this.EncryptPassword(buffer7, this.LegacyPasswordCompatibilityMode); } return Convert.ToBase64String(inArray); } 

现在,在我的特定场景中,我没有任何密码 – 因为我的旧身份validation模块没有使用它,因此string salt是空的,就像byte [] src 。 默认情况下使用的散列算法是HMACSHA256,它是一个键控散列函数。 因此我们进入这个for -loop,其中num2 始终为0.由于num2也用作增量器,我们进入无限循环。

算法不应该针对这种特殊情况进行测试吗? 难道这不是一个简单的错误,只是通过UnitTesting代码捕获? 还是我忽略了什么?

我不是安全专家,所以我无法回答你的问题。

以下是新ASP.Net Universal Provider使用的EncodePassword方法。

它与旧的MembershipProvider有点不同。 你可能想尝试一下。

 private string EncodePassword(string pass, int passwordFormat, string salt) { byte[] numArray; byte[] numArray1; string base64String; bool length = passwordFormat != 0; if (length) { byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] numArray2 = Convert.FromBase64String(salt); byte[] numArray3 = null; length = passwordFormat != 1; if (length) { numArray1 = new byte[(int)numArray2.Length + (int)bytes.Length]; Buffer.BlockCopy(numArray2, 0, numArray1, 0, (int)numArray2.Length); Buffer.BlockCopy(bytes, 0, numArray1, (int)numArray2.Length, (int)bytes.Length); numArray3 = this.EncryptPassword(numArray1); } else { HashAlgorithm hashAlgorithm = this.GetHashAlgorithm(); length = hashAlgorithm as KeyedHashAlgorithm <= null; if (length) { numArray1 = new byte[(int)numArray2.Length + (int)bytes.Length]; Buffer.BlockCopy(numArray2, 0, numArray1, 0, (int)numArray2.Length); Buffer.BlockCopy(bytes, 0, numArray1, (int)numArray2.Length, (int)bytes.Length); numArray3 = hashAlgorithm.ComputeHash(numArray1); } else { KeyedHashAlgorithm keyedHashAlgorithm = (KeyedHashAlgorithm)hashAlgorithm; length = (int)keyedHashAlgorithm.Key.Length != (int)numArray2.Length; if (length) { length = (int)keyedHashAlgorithm.Key.Length >= (int)numArray2.Length; if (length) { numArray = new byte[(int)keyedHashAlgorithm.Key.Length]; int num = 0; while (true) { length = num < (int)numArray.Length; if (!length) { break; } int num1 = Math.Min((int)numArray2.Length, (int)numArray.Length - num); Buffer.BlockCopy(numArray2, 0, numArray, num, num1); num = num + num1; } keyedHashAlgorithm.Key = numArray; } else { numArray = new byte[(int)keyedHashAlgorithm.Key.Length]; Buffer.BlockCopy(numArray2, 0, numArray, 0, (int)numArray.Length); keyedHashAlgorithm.Key = numArray; } } else { keyedHashAlgorithm.Key = numArray2; } numArray3 = keyedHashAlgorithm.ComputeHash(bytes); } } base64String = Convert.ToBase64String(numArray3); } else { base64String = pass; } return base64String; }