Asp.net
將密碼格式從加密更改為散列
我發現關於將現有數據庫從加密密碼轉換為散列密碼的資訊非常少。(我能夠找到更多關於轉換另一種方式的資訊,但這並沒有太大幫助。)
大多數人都知道,更改
passwordFormatweb.config 中的設置只會影響新使用者。我有一個有幾百個使用者的數據庫,我想將它們轉換為使用散列密碼而不更改那些現有的密碼。有沒有其他人熟悉如何處理這個問題?感謝您的任何提示。
這是我開始的方法,看看我能走多遠:
- 在我的 web.config 中創建兩個 MembershipProvider,一個用於加密密碼,一個用於散列。
- 使用加密密碼提供程序遍歷所有使用者。( SqlMembershipProvider.GetAllUsers )
- 使用加密密碼提供程序獲取使用者密碼。( MembershipUser.GetPassword )
- 使用散列密碼提供程序將使用者的密碼更改為相同的密碼。( MembershipUser.ChangePassword )
所以它會是這樣的:
<membership defaultProvider="HashedProvider"> <providers> <clear /> <add name="HashedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="false" requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Hashed" type="System.Web.Security.SqlMembershipProvider" /> <add name="EncryptedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Encrypted" type="System.Web.Security.SqlMembershipProvider" /> </providers> </membership>程式碼:
SqlMembershipProvider hashedProvider = (SqlMembershipProvider)Membership.Providers["HashedProvider"]; SqlMembershipProvider encryptedProvider = (SqlMembershipProvider)Membership.Providers["EncryptedProvider"]; int unimportant; foreach (MembershipUser user in encryptedProvider.GetAllUsers(0, Int32.MaxValue, out unimportant )) { hashedProvider.ChangePassword(user.UserName, user.GetPassword(), user.GetPassword()); }
Greg 的解決方案是一個好的開始,但不會影響現有使用者。SqlMembershipProvider 通過將 PasswordFormat(0=clear、1=Hashed、2=Encrypted)與密碼一起儲存在表中來保護現有使用者和密碼。更改提供者密碼格式只會影響對使用者表的插入。為了將現有使用者的密碼轉換為 Hashed,您必須更改每個條目的 PasswordFormat 參數。這是一個簡單的方法來做到這一點:
void HashAllPasswords() { var clearProvider = Membership.Providers["SqlProvider_Clear"]; var hashedProvider = Membership.Providers["SqlProvider_Hashed"]; int dontCare; if (clearProvider == null || hashedProvider == null) return; var passwords = clearProvider.GetAllUsers(0, int.MaxValue, out dontCare) .Cast<MembershipUser>().ToDictionary(u => u.UserName, u => u.GetPassword()); using (var conn = new SqlConnection( ConfigurationManager.ConnectionStrings[0].ConnectionString)) { conn.Open(); using (var cmd = new SqlCommand( "UPDATE [aspnet_Membership] SET [PasswordFormat]=1", conn)) cmd.ExecuteNonQuery(); } foreach (var entry in passwords) { var resetPassword = hashedProvider.ResetPassword(entry.Key, null); hashedProvider.ChangePassword(entry.Key, resetPassword, entry.Value); } }