2010-03-30 33 views
12

Tôi đang sử dụng trang web làm giao diện người dùng và tất cả người dùng được xác thực với Nhà cung cấp tư cách thành viên ASP.NET chuẩn. Mật khẩu được lưu "băm" trong cơ sở dữ liệu SQL.Làm thế nào để tạo một nhà cung cấp thành viên asp.net băm mật khẩu theo cách thủ công?

Bây giờ tôi muốn viết một máy tính để bàn-khách hàng với các chức năng quản trị. Trong số những thứ khác cần có một phương pháp để thiết lập lại mật khẩu người dùng. Tôi có thể truy cập cơ sở dữ liệu bằng dữ liệu thành viên đã lưu, nhưng làm cách nào để tôi có thể tạo mật khẩu và muối một cách thủ công? Sử dụng System.Web.Membership Namespace có vẻ không phù hợp vì vậy tôi cần phải biết cách tạo muối và hàm băm của mật khẩu mới theo cách thủ công.

Các chuyên gia bước lên! :)

+2

Tại sao System.Web.Security không phù hợp? Có vẻ như công cụ thích hợp cho công việc. –

+0

Tôi không thể bao gồm nhà cung cấp thành viên trong ứng dụng dành cho máy tính để bàn, sử dụng cơ sở dữ liệu sql của tôi, phải không? Khi có thể bạn đúng và tôi có thể sử dụng những phương pháp này ... nhưng làm thế nào để thực hiện nó? – Anheledir

Trả lời

13

Bạn hoàn toàn có thể sử dụng System.Web.Security trong một giao diện điều khiển hoặc winforms ứng dụng.

Dưới đây là một giao diện điều khiển ứng dụng đơn giản:

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(); 
} 

Và 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

phương pháp bẩn nhanh

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 

Mặc dù, không gian tên thành viên đã được xây dựng trong các công cụ cho việc này là tốt, như đã nêu bởi Quên chấm phẩy

+0

Phương pháp đẹp nhưng không giống như tiêu chuẩn asp.nhà cung cấp thành viên net đang sử dụng - sau khi đặt mật khẩu mới bằng phương pháp này, người dùng không thể đăng nhập được nữa. Cảm ơn anyway :) – Anheledir

+1

Tôi đang sử dụng mã này với các nhà cung cấp thành viên asp.net trên một trang web sản xuất (một cũ), bạn recompute băm và muối chính và so sánh trên mỗi xác thực, đó là nơi an ninh có nguồn gốc từ. Không phải là cầu kỳ, nhưng câu hỏi của bạn chỉ hỏi làm thế nào để tính toán muối và có chìa khóa bằng tay. –

1

Đã một thời gian kể từ khi tôi đã tinkered với ASP .Net thành viên, nhưng hãy nhớ giao dịch với một cái gì đó một chút liên quan đến nó (cần thiết để tùy chỉnh mọi thứ do một cơ sở dữ liệu hiện có của người dùng). Trong nỗ lực đó tôi đã overrode các phương thức (db người dùng hiện tại có md5 băm pwds).

Vì vậy, trong "dòng suy nghĩ" như nhau:

Expose API thành viên thông qua một dịch vụ web mà ứng dụng máy tính để bàn của bạn có thể tham khảo. Bằng cách này, bạn không phải là "tái tạo" mọi thứ, bạn đang tái sử dụng chúng. Bạn không cần phải ghi đè lên bất kỳ thứ gì, bạn chỉ cần hiển thị các phương thức hiện có thông qua dịch vụ web cho ứng dụng dành cho máy tính để bàn của bạn.

Goes mà không nói rằng bạn phải đảm bảo thiết bị đầu cuối này ....

Nếu ở trên là quá sơ sài cho khẩu vị của bạn, đây là một liên kết đến các diễn đàn asp.net về một số nỗ lực để tái băm .... tôi không thể xác nhận tính chính xác, nhưng nó phải là dễ dàng để kiểm tra nó ra:

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

+0

Cảm ơn bạn đã có ý tưởng về dịch vụ web. Bạn nói đúng, trong điều kiện bình thường tôi sẽ làm cho toàn bộ thành viên-Thing có sẵn thông qua một dịch vụ. Rất tiếc, các chính sách của công ty không cho phép loại dịch vụ web này: ( – Anheledir

15

tôi đã sử dụng phản xạ để có một cái nhìn vào những phương pháp NET-Framework được sử dụng nội bộ. Có lẽ có phương pháp công khai có sẵn cho điều này nhưng tôi không tìm thấy chúng - nếu bạn biết cách truy vấn các phương thức nội bộ đó như một người dùng, hãy để lại một bình luận! :)

Đây là đơn giản hóa mã nguồn mà không cần điều kiện không cần thiết bởi vì tôi chỉ muốn mã hóa các mật khẩu như một 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); 
} 
+8

không cần sử dụng Trình phản xạ, nguồn cho nhà cung cấp mặc định sẵn có - http://download.microsoft.com/download/a/b/3 /ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi Hãy xem phương thức EncodePassword của SqlMembershipProvider để thực hiện, sử dụng thuật toán băm mặc định trừ khi một được chỉ định cho MembershipProvider. IIRC, mặc định là SHA-1 –

Các vấn đề liên quan