有没有在ASP.NET DefaultMembershipProvider的散列函数中的错误? [英] Is there a bug in the hashfunction of the ASP.NET DefaultMembershipProvider?
问题描述
我迁移我的遗产ASP.NET Web表单应用程序开始使用ASP.NET内置的DefaultMembershipProvider。用我的旧homebrewn authenticationmodule存储密码的哈希SHA256。我想,'升级'到DefaultMembershipProvider,这也哈希存储在SQL数据库,将意味着我可以迁移这些散列以及因此提供现有用户升级无痛(这样他们就不必重置其密码)。
I am migrating my legacy ASP.NET webforms application to start using the ASP.NET build-in DefaultMembershipProvider. My old homebrewn authenticationmodule used to store SHA256 hashes of passwords. I figured that 'upgrading' to the DefaultMembershipProvider, which also stores hashes in the SQL DB, would mean that I could migrate these hashes as well and therefore offer painless upgrade for current users (so they wouldn't have to reset their password).
现在,这并没有按计划相当的工作,我开始寻找到DefaultMembershipProvider源(更具体的,在这里(很明显!)的 https://github.com/wyxy2005/bluceNet/tree/master/System.Web.Providers )和我来到翻过下面的函数:
Now, this didn't quite work as planned (obviously!) and I started to look into the source of the DefaultMembershipProvider (to be more specific, right here: https://github.com/wyxy2005/bluceNet/tree/master/System.Web.Providers) and I came accross the following function:
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);
}
现在,我在特定的场景,我没有任何密码盐我原来的认证模块并没有那么字符串盐
是空的,为的是用它字节[]的src
。这是默认使用的哈希算法是HMACSHA256,这是一个键控散列函数。因此,我们进入这个为
-loop其中 NUM2
是始终 0。 NUM2
也被用来作为增量,我们进入一个无限循环。
Now, in my particular scenario I didn't have any password-salt as my old authentication module didn't use it so string salt
is empty, as is byte [] src
. The hashing algorithm that is used by default is HMACSHA256, which is a keyed hashfunction. So we get into this for
-loop where num2
is always 0. As num2
is also used as the incrementer, we enter an infinite loop.
不应该为这种特定条件的算法测试?不应该这样一直一个简单的错误,通过简单的单元测试的code抓?还是我忽视的东西?
推荐答案
我不是一个安全专家,所以我不能回答你的问题。
I'm not a security expert, so I cannot answer your question.
下面是新的<二手恩codePassword方法href=\"http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx\"相对=nofollow> ASP.Net通用提供商。
这是从旧的MembershipProvider有点不同。你可能想给一个尝试。
It is a little bit different from old MembershipProvider. You might want to give a try.
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;
}
这篇关于有没有在ASP.NET DefaultMembershipProvider的散列函数中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!