2010-03-30 39 views
12

我使用網站作爲前端,所有用戶都使用標準ASP.NET Membership-Provider進行身份驗證。密碼在SQL數據庫中保存爲「散列」。如何手動創建一個asp.net成員資格提供程序散列密碼?

現在我想編寫一個具有管理功能的桌面客戶端。除其他外,應該有一種重置用戶密碼的方法。我可以使用已保存的成員數據訪問數據庫,但是如何手動創建密碼 - 鹽和-hash?使用System.Web.Membership命名空間似乎是不合適的,因此我需要知道如何手動創建新密碼的salt和hash。

專家加強! :)

+2

爲什麼System.Web.Security不合適?似乎是正確的工具。 – 2010-03-30 18:10:57

+0

我不能在桌面客戶端應用程序中使用我的sql數據庫包含成員資格提供程序,可以嗎?如果可能,你是對的,我可以使用這些方法......但如何實現它? – Anheledir 2010-03-30 18:42:51

回答

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", "[email protected]", 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> 
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 

雖然隸屬命名空間的東西建在這個爲好,如忘記分號

+0

不錯的方法,但不是標準的ASP相同。網絡會員供應商正在使用 - 在用此方法設置新密碼後,用戶無法再登錄。無論如何,謝謝:) – Anheledir 2010-03-31 09:11:57

+1

我使用此代碼與生產站點(舊的)上的asp.net成員資格提供程序,您重新計算散列和salt密鑰,並比較每個身份驗證,這是安全性的來源。不挑剔,但你的問題只問如何計算鹽和手動鍵。 – 2010-04-05 15:37:56

1

它已經有一段時間,因爲我已經與ASP修修補補規定.Net會員資格,但是請記住處理與它有關的事情(由於現有的用戶數據庫需要定製事物)。在這方面,我重寫了這些方法(現有的用戶數據庫有md5散列密碼)。

所以在相同的「思想路線」:

暴露通過您的桌面應用程序可以引用一個Web服務API的成員。這樣,你不是「重新創造」的東西,你正在重新使用它們。您不必重寫任何內容,只需通過Web服務爲您的桌面應用程序公開現有方法即可。

不用說,你必須確保這個端點....

如果上面是你的口味過於簡略,這裏有關於一些嘗試重新散列到asp.net論壇的鏈接....我無法證實的準確性,但它應該很容易測試出來:

http://forums.asp.net/p/1336657/2899172.aspx

+0

感謝您的網絡服務理念。你是對的,在正常情況下,我會通過服務提供所有會員資格。不幸的是,公司政策不允許使用這種網絡服務:( – Anheledir 2010-03-31 09:07:37

15

我使用反射來看一看在.NET的框架是使用內部的那些方法。也許有公共方法可用,但我沒有找到它們 - 如果你知道如何查詢這些內部方法作爲用戶,請留下評論! :)

這裏是沒有不必要的條件簡化源代碼,因爲我只想編碼密碼作爲SHA1散列:

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); 
} 
+8

不需要使用Reflector,默認提供商的源代碼已經可用 - http://download.microsoft.com/download/a/b/3 /ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi。查看SqlMembershipProvider的EncodePassword方法的實現。它使用默認的散列算法,除非爲MembershipProvider指定了一個。IIRC,默認值是SHA-1 – 2010-03-31 20:29:55

相關問題