我使用网站作为前端,所有用户都使用标准的ASP.NET Membership-Provider进行身份验证。密码在SQL数据库中保存为“哈希”。
现在我想编写一个具有管理功能的桌面客户端。除其他事项外,应该有一种重置用户密码的方法。我可以使用保存的成员资格数据访问数据库,但是如何手动创建password-salt和-hash?使用System.Web.Membership命名空间似乎不合适,所以我需要知道如何手动创建新密码的salt和hash。
专家加紧! :)
答案 0 :(得分:15)
我使用了反射器来查看.NET-Framework使用内部的那些方法。也许有公共方法可用于此但我没有找到它们 - 如果你知道如何查询这些内部方法作为用户请发表评论! :)
以下是没有不必要条件的简化源代码,因为我只想将密码编码为SHA1-Hash:
private string GenerateSalt() {
var buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
private string EncodePassword(string pass, string salt) {
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(salt);
byte[] dst = new byte[src.Length + bytes.Length];
byte[] inArray = null;
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
答案 1 :(得分:13)
您绝对可以在控制台或winforms应用中使用System.Web.Security
。
这是一个简单的控制台应用程序:
static void Main(string[] args)
{
MembershipProvider provider = Membership.Provider;
MembershipUser myUser = provider.GetUser("myUser", false);
if( myUser != null ) provider.DeleteUser("myUser", true);
MembershipCreateStatus status;
myUser = provider.CreateUser("myUser", "password", "user@example.com", null, null, true, null, out status);
if (status != MembershipCreateStatus.Success)
{
Console.WriteLine("Could not create user. Reason: " + status.ToString());
Console.ReadLine();
return;
}
Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString());
string newPassword = myUser.ResetPassword();
Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString());
Console.WriteLine("Authenticating with new password: " + provider.ValidateUser("myUser", newPassword).ToString());
Console.ReadLine();
}
app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyConnectionString" connectionString="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear />
<add name="MyMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MyConnectionString"
applicationName="MyApplication"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false" />
</providers>
</membership>
</system.web>
</configuration>
答案 2 :(得分:1)
快速脏方法
Public Shared Function GetSaltKey() As String
Dim saltBytes() As Byte
Dim minSaltSize As Integer = 4
Dim maxSaltSize As Integer = 8
' Generate a random number for the size of the salt.
Dim random As Random
random = New Random()
Dim saltSize As Integer
saltSize = random.Next(minSaltSize, maxSaltSize)
' Allocate a byte array, which will hold the salt.
saltBytes = New Byte(saltSize - 1) {}
' Initialize a random number generator.
Dim rng As RNGCryptoServiceProvider
rng = New RNGCryptoServiceProvider()
' Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes)
' Convert plain text into a byte array.
Return Convert.ToBase64String(saltBytes)
End Function
Public Shared Function ComputeHash(ByVal password As String, ByVal salt As String) As String
Return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(salt & password, _
System.Web.Configuration.FormsAuthPasswordFormat.SHA1.ToString)
End Function
尽管如此,如遗忘分号所述,成员资格名称空间也内置了内容
答案 3 :(得分:1)
已经有一段时间了,因为我修改了ASP.Net成员资格,但是记得要处理与它有点相关的事情(需要根据现有的用户数据库来定制事物)。在那个努力中我覆盖了方法(现有的用户db有md5哈希pwds)。
所以在同一“思路”中:
通过桌面应用可以引用的网络服务公开Membership API。这样,你就不会“重新创造”东西,而是重新使用它们。您不必覆盖任何内容,只需通过桌面应用程序的Web服务公开现有方法。
不言而喻,你必须确保这个终点....
如果上面的内容过于粗略,请点击asp.net论坛关于重新创建哈希的一些尝试....我无法确认准确性,但应该很容易测试出来: