AspNet 会员加密密码生成
AspNet Membership Encrypted Password Generation
在我们开始之前,我想明确表示我知道这个问题有多糟糕。这是一个糟糕的情况,但我受到一些非常奇怪的规范的限制。
我知道你不仅不应该尝试为这类东西编写自己的包装器,but Microsoft have made it clear this shouldn't even be used。因此,在您开始写回复说 "Why are you even doing this" 之前,请尝试了解我已经与我的上级进行过这些对话,但是推动新功能和缺乏时间意味着尽管它很残酷;尽管如此-我在这里。
我们有一个 ASP 网络会员数据库,在我加入这家公司之前就开始了,现在拥有大约 4 万名用户。我们在 .Net 3.5 中有一个允许用户登录的平台。
我目前的工作是在 .Net Core 2.1 中编写一个 API,其中一部分是允许用户创建和更新,但问题就在于此——从 Membership 迁移到 Identity 不是一个选项,所以我被告知要为 Membership 数据库中的存储过程创建一个包装器。
这基本上是成功的,唯一的问题是;这个问题的主题。通过 aspnet_Membership_CreateUser
创建用户 我需要以能够在我们的平台上成功验证的方式提交数据。
我最初关注 this post 但发现它是为 PasswordFormat 1 - Hashed 设计的;然后我发现我们的用户群使用 PasswordFormat 2 - Encrypted,因此我创建的用户不会验证。
代码看起来像这样
public bool CreateUser(string userName, string password, string email, string securityQuestion, string securityAnswer, bool isApproved)
{
bool success = false;
//Just so I can attempt to login afterwards
password = "Hello World!";
//Our password and password salt need to be base64 encoded before we can save them to the DB
string salt = Guid.NewGuid().ToString();
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(Encoding.UTF8).Concat(password.GetBytes(Encoding.UTF8));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1' T-SQL
byte[] sha1HashedPass = PasswordHelper.HashBytes(_validationMethod, saltedpass.ToArray(), _validationKey);
string hashedPass = sha1HashedPass.ToBase64String();
int errorCode = MembershipCreateUser(_applicationName, userName, hashedPass, encryptedSalt, email, securityQuestion, securityAnswer, isApproved);
if (errorCode == 0)
{
success = true;
}
return success;
}
值得注意的是 _validationKey
是在使用此数据库的应用程序之间共享的机器密钥,我将其传递给 SHA1 机制。
因此,抛开故意和糟糕的安全做法不谈;
C# 中有没有办法以这种方式生成加密的(未散列的)密码和盐?
感谢您的评论 - 谢天谢地,我们能够在我们的平台中支持散列密码;问题出在我的代码上,而不是 ASP 会员资格。
如前所述,我正在使用 originally written in T-SQL 的 post 并尝试构建它的 C# 实现。我对这段代码的实现是不正确的,因此我生成的密码和盐无法通过 ASP Net Membership 验证,这在我原来的 post 中并不明显,因为我混淆了方法这是 SHA1 散列我的数据。
//Using hard coded just for example
string username = "joeborder";
string password = "Hello World!";
string salt = "TastySalt";
Encoding encoder = Encoding.Unicode; //Encoding was also incorrect
//Our password and password salt need to be base64 encoded before we can save them to the DB
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(encoder).Concat(password.GetBytes(encoder));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1') T-SQL
var SHA1Hasher = new SHA1CryptoServiceProvider(); //Originally I was using HMACSHA1 which was producing a different output
byte[] sha1HashedPass = SHA1Hasher.ComputerHash(saltedpass.ToArray());
string hashedPass = sha1HashedPass.ToBase64String();
/*
EXEC aspnet_Membership_CreateUser
@ApplicationName = "MyApp",
@UserName = username,
@Password = hashedPass,
@PasswordSalt = encryptedSalt,
...Etc
*/
然后在我们的 .Net 3.5 应用程序中,以下代码将起作用
string username = "joeborder";
string password = "Hello World!";
if (Membership.ValidateUser(username, password))
{
Console.WriteLine("You've gotta be kidding me thats a clutch");
}
在我们开始之前,我想明确表示我知道这个问题有多糟糕。这是一个糟糕的情况,但我受到一些非常奇怪的规范的限制。
我知道你不仅不应该尝试为这类东西编写自己的包装器,but Microsoft have made it clear this shouldn't even be used。因此,在您开始写回复说 "Why are you even doing this" 之前,请尝试了解我已经与我的上级进行过这些对话,但是推动新功能和缺乏时间意味着尽管它很残酷;尽管如此-我在这里。
我们有一个 ASP 网络会员数据库,在我加入这家公司之前就开始了,现在拥有大约 4 万名用户。我们在 .Net 3.5 中有一个允许用户登录的平台。
我目前的工作是在 .Net Core 2.1 中编写一个 API,其中一部分是允许用户创建和更新,但问题就在于此——从 Membership 迁移到 Identity 不是一个选项,所以我被告知要为 Membership 数据库中的存储过程创建一个包装器。
这基本上是成功的,唯一的问题是;这个问题的主题。通过 aspnet_Membership_CreateUser
创建用户 我需要以能够在我们的平台上成功验证的方式提交数据。
我最初关注 this post 但发现它是为 PasswordFormat 1 - Hashed 设计的;然后我发现我们的用户群使用 PasswordFormat 2 - Encrypted,因此我创建的用户不会验证。
代码看起来像这样
public bool CreateUser(string userName, string password, string email, string securityQuestion, string securityAnswer, bool isApproved)
{
bool success = false;
//Just so I can attempt to login afterwards
password = "Hello World!";
//Our password and password salt need to be base64 encoded before we can save them to the DB
string salt = Guid.NewGuid().ToString();
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(Encoding.UTF8).Concat(password.GetBytes(Encoding.UTF8));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1' T-SQL
byte[] sha1HashedPass = PasswordHelper.HashBytes(_validationMethod, saltedpass.ToArray(), _validationKey);
string hashedPass = sha1HashedPass.ToBase64String();
int errorCode = MembershipCreateUser(_applicationName, userName, hashedPass, encryptedSalt, email, securityQuestion, securityAnswer, isApproved);
if (errorCode == 0)
{
success = true;
}
return success;
}
值得注意的是 _validationKey
是在使用此数据库的应用程序之间共享的机器密钥,我将其传递给 SHA1 机制。
因此,抛开故意和糟糕的安全做法不谈; C# 中有没有办法以这种方式生成加密的(未散列的)密码和盐?
感谢您的评论 - 谢天谢地,我们能够在我们的平台中支持散列密码;问题出在我的代码上,而不是 ASP 会员资格。
如前所述,我正在使用 originally written in T-SQL 的 post 并尝试构建它的 C# 实现。我对这段代码的实现是不正确的,因此我生成的密码和盐无法通过 ASP Net Membership 验证,这在我原来的 post 中并不明显,因为我混淆了方法这是 SHA1 散列我的数据。
//Using hard coded just for example
string username = "joeborder";
string password = "Hello World!";
string salt = "TastySalt";
Encoding encoder = Encoding.Unicode; //Encoding was also incorrect
//Our password and password salt need to be base64 encoded before we can save them to the DB
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(encoder).Concat(password.GetBytes(encoder));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1') T-SQL
var SHA1Hasher = new SHA1CryptoServiceProvider(); //Originally I was using HMACSHA1 which was producing a different output
byte[] sha1HashedPass = SHA1Hasher.ComputerHash(saltedpass.ToArray());
string hashedPass = sha1HashedPass.ToBase64String();
/*
EXEC aspnet_Membership_CreateUser
@ApplicationName = "MyApp",
@UserName = username,
@Password = hashedPass,
@PasswordSalt = encryptedSalt,
...Etc
*/
然后在我们的 .Net 3.5 应用程序中,以下代码将起作用
string username = "joeborder";
string password = "Hello World!";
if (Membership.ValidateUser(username, password))
{
Console.WriteLine("You've gotta be kidding me thats a clutch");
}