Как создать хеш-пароль провайдера asp.net вручную? - PullRequest
13 голосов
/ 30 марта 2010

Я использую веб-сайт в качестве внешнего интерфейса, и все пользователи проходят проверку подлинности с помощью стандартного поставщика членства ASP.NET. Пароли сохраняются в хеше в базе данных SQL.

Теперь я хочу написать десктоп-клиент с административными функциями. Среди прочего должен быть способ сброса пароля пользователя. Я могу получить доступ к базе данных с сохраненными данными о членстве, но как я могу вручную создать пароль-соль и -hash? Использование пространства имен System.Web.Membership представляется неуместным, поэтому мне нужно знать, как вручную создавать соль и хэш нового пароля.

Эксперты наращивают! :)

Ответы [ 4 ]

15 голосов
/ 31 марта 2010

Я использовал рефлектор, чтобы взглянуть на те методы, которые использует .NET-Framework для внутреннего использования. Возможно, для этого есть открытые методы, но я их не нашел - если вы знаете, как запрашивать эти внутренние методы как пользователь, оставьте комментарий! :)

Вот упрощенный исходный код без лишних условий, потому что я хочу только закодировать пароль как 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);
}
13 голосов
/ 01 апреля 2010

Вы можете использовать System.Web.Security в консоли или в приложении winforms.

Вот простое консольное приложение:

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>
1 голос
/ 31 марта 2010

Прошло некоторое время с тех пор, как я возился с членством в ASP.Net, но не забывайте иметь дело с чем-то немного связанным с этим (необходимым для настройки вещей из-за существующей базы данных пользователей). В этом случае я переопределил методы (у существующего пользователя db хэшированные pwds md5).

Итак, в той же «линии мысли»:

Предоставьте API членства через веб-сервис, на который может ссылаться ваше настольное приложение. Таким образом, вы не «воссоздаете» вещи, а используете их заново. Вам не нужно ничего переопределять, вы просто выставляете существующие методы через веб-сервис для вашего настольного приложения.

Само собой разумеется, что вам нужно защитить эту конечную точку ....

Если вышеупомянутое слишком схематично на ваш вкус, вот ссылка на форумы asp.net относительно некоторых попыток воссоздать хеширование .... Я не могу подтвердить точность, но это должно быть легко проверить :

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

1 голос
/ 30 марта 2010

Быстрый грязный метод

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

Несмотря на то, что пространство имен членства имеет встроенные средства для этого, как говорится в Forgotten Semicolon

...