ASP.NET成员如何生成其salt密钥,然后如何对其进行编码(即,是salt +密码还是密码+ salt)?
我正在使用SHA-1和我的会员资格,但我想重新创建相同的盐,所以内置的会员资格可以像我的东西一样散列东西.
编辑2:没关系.我误读了它并且认为它说的是字节,而不是位.所以我传入128个字节,而不是128位.
编辑:我一直试图这样做.这就是我的意思,
public string EncodePassword(string password, string salt)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] src = Encoding.Unicode.GetBytes(salt);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
private byte[] createSalt(byte[] saltSize)
{
byte[] saltBytes = saltSize;
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return saltBytes;
}
所以我没有试过看看ASP.NET成员资格是否会识别这个,但散列密码看起来很接近.我只是不知道如何将它转换为base64 for salt.
我这样做了
byte[] storeSalt = createSalt(new byte[128]);
string salt = Encoding.Unicode.GetString(storeSalt);
string base64Salt = Convert.ToBase64String(storeSalt);
int test = base64Salt.Length;
测试长度是172,远远超过128位,所以我做错了什么?
这就是他们的盐的样子
vkNj4EvbEPbk1HHW+K8y/A==
这就是我的盐的样子
E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI=
Kelly Gendro.. 20
ASP.NET成员资格使用的默认哈希算法是什么?对他们的默认算法进行了很好的讨论.
我希望有所帮助!
编辑 - 我所指的答案是顶部帖子中的代码,
public string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); //byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013 byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inArray); }
他们使用BlockCopy组合Unicode Salt + Pass
- 回答你的问题:
两种算法都是必要的,并履行不同的角色
RNG Crypto用于生成盐.它基本上是一长串随机数据.这是基于每个用户生成和存储的.通常,这是在创建用户或更改密码时完成的.
BlockCopy只是他们用来组合salt和密码的方法.上面的代码基本上等于salt +密码.
您无法重新创建盐值,因为它是完全随机的.但是,它由框架为每个用户存储.
将salt与密码组合并使用上述技术对其进行散列将允许您使用框架存储的散列值来验证用户密码.
我想我们都以不同的方式阅读你的问题.我发布的代码不会生成您的salt,但它会让您以与ASP.NET成员身份兼容的方式使用它.
对不起,我的解释不是最好的 - 它能回答你的问题吗?
ASP.NET成员资格使用的默认哈希算法是什么?对他们的默认算法进行了很好的讨论.
我希望有所帮助!
编辑 - 我所指的答案是顶部帖子中的代码,
public string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); //byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013 byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inArray); }
他们使用BlockCopy组合Unicode Salt + Pass
- 回答你的问题:
两种算法都是必要的,并履行不同的角色
RNG Crypto用于生成盐.它基本上是一长串随机数据.这是基于每个用户生成和存储的.通常,这是在创建用户或更改密码时完成的.
BlockCopy只是他们用来组合salt和密码的方法.上面的代码基本上等于salt +密码.
您无法重新创建盐值,因为它是完全随机的.但是,它由框架为每个用户存储.
将salt与密码组合并使用上述技术对其进行散列将允许您使用框架存储的散列值来验证用户密码.
我想我们都以不同的方式阅读你的问题.我发布的代码不会生成您的salt,但它会让您以与ASP.NET成员身份兼容的方式使用它.
对不起,我的解释不是最好的 - 它能回答你的问题吗?
以下是SQLMembershipProvider如何生成salt.
private string GenerateSalt() { var buf = new byte[16]; (new RNGCryptoServiceProvider()).GetBytes(buf); return Convert.ToBase64String(buf); }
您可以在此处下载ASP.NET的SQL提供程序代码.
我遇到的问题是在IIS7上运行的开发应用程序..NET 4.0使用的是与默认的HashAlgorithmType for .NET 2.0不同的默认哈希算法.
在Microsoft的"EncodePassword"示例代码中Membership.HashAlgorithmType
,如果未在框架中指定,它们引用我认为返回框架的默认值web.config
.
我能够将这个GenerateSalt和EncodePassword方法都用于我的应用程序.
我的组合代码:
internal string GenerateSalt() { byte[] buf = new byte[16]; (new RNGCryptoServiceProvider()).GetBytes(buf); return Convert.ToBase64String(buf); } internal string EncodePassword(string pass, int passwordFormat, string salt) { if (passwordFormat == 0) // MembershipPasswordFormat.Clear return pass; byte[] bIn = Encoding.Unicode.GetBytes(pass); byte[] bSalt = Convert.FromBase64String(salt); byte[] bAll = new byte[bSalt.Length + bIn.Length]; byte[] bRet = null; Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); if (passwordFormat == 1) { // MembershipPasswordFormat.Hashed HashAlgorithm s = HashAlgorithm.Create("SHA1"); // Hardcoded "SHA1" instead of Membership.HashAlgorithmType bRet = s.ComputeHash(bAll); } else { bRet = EncryptPassword(bAll); } return Convert.ToBase64String(bRet); }