简体   繁体   English

如何手动创建asp.net成员资格提供程序的哈希密码?

[英]How to create a asp.net membership provider hashed password manually?

I'm using a website as a frontend and all users are authenticated with the standard ASP.NET Membership-Provider. 我使用网站作为前端,并且所有用户都通过标准ASP.NET Membership-Provider进行了身份验证。 Passwords are saved "hashed" within a SQL-Database. 密码被“散列”保存在SQL数据库中。

Now I want to write a desktop-client with administrative functions. 现在,我想编写一个具有管理功能的桌面客户端。 Among other things there should be a method to reset a users password. 除其他事项外,应该有一种重置用户密码的方法。 I can access the database with the saved membership-data, but how can I manually create the password-salt and -hash? 我可以使用保存的成员资格数据访问数据库,但是如何手动创建password-salt和-hash? Using the System.Web.Membership Namespace seems to be inappropriate so I need to know how to create the salt and hash of the new password manually. 使用System.Web.Membership命名空间似乎是不合适的,因此我需要知道如何手动创建新密码的盐和哈希。

Experts step up! 专家加紧! :) :)

I used reflector to take a look at those methods the .NET-Framework is using internal. 我使用反射器来查看.NET-Framework正在使用内部的那些方法。 Maybe there are public methods available for this but I did not find them - if you know how to query those internal methods as a user please left a comment! 也许有一些可用的公共方法,但是我没有找到它们-如果您知道如何以用户身份查询这些内部方法,请留下评论! :) :)

Here is the simplified source-code without unnecessary conditions because I only want to encode the password as a SHA1-Hash: 这是简化的源代码,没有不必要的条件,因为我只想将密码编码为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);
}

You can absolutely use System.Web.Security within a console or winforms app. 您绝对可以在控制台或winforms应用程序中使用System.Web.Security

Here's a simple console application: 这是一个简单的控制台应用程序:

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

And the app.config: 和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>

Quick dirty method 快速脏法

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

Although, the membership namespace has stuff built in for this as well, as stated by Forgotten Semicolon 不过,正如Forgotten Semicolon所说,成员名称空间也为此内置了东西

It's been some time since I've tinkered with ASP.Net membership, but do remember dealing with something a bit related to it (needed to customize things due to an existing database of users). 自从我修改ASP.Net成员资格已有一段时间了,但是请记住要处理一些与之相关的事情(由于现有的用户数据库,需要自定义内容)。 In that effort I overrode the methods (the existing user db had md5 hashed pwds). 在此过程中,我覆盖了方法(现有的用户db的md5哈希了pwds)。

So in the same "line of thought": 因此,在相同的“思路”中:

Expose the Membership API via a web service that your desktop app can reference. 通过桌面应用程序可以引用的Web服务公开Membership API。 This way, you're not "re-creating" things, you're re-using them. 这样,您就不会“重新创建”事物,而是在重复使用它们。 You don't have to override anything, you're just exposing the existing methods via a web service for your desktop app. 您不必重写任何内容,只需通过Web服务为桌面应用程序公开现有方法。

Goes without saying that you'd have to secure this endpoint.... 不用说,您必须保护此端点。

If the above is too sketchy for your taste, here's a link to the asp.net forums regarding some attempts to recreate the hashing....I can't confirm the accuracy, but it should be easy to test it out: 如果以上内容都不适合您使用,请访问以下链接到asp.net论坛,其中包含有关尝试重新创建哈希的一些尝试。...我无法确认准确性,但应该可以轻松地对其进行测试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果您不知道当前密码,如何使用asp.net成员资格提供程序更改散列密码? - How do you change a hashed password using asp.net membership provider if you don't know the current password? 使用ASP.NET成员资格提供程序(哈希格式),我无法重置密码 - Using the ASP.NET membership provider (hashed password format) I am unable to reset password 如何手动更改asp.net会员密码? - How to manually change password in asp.net membership? asp.net成员身份:哈希密码时如何检查密码答案是否正确 - asp.net membership: how to check if password answer is correct when password hashed 在asp.net中使用哈希密码创建登录名 - Create login with hashed password in asp.net 使用ASP.Net会员提供商忘记密码? - Forgot password using ASP.Net membership provider? 电子邮件替换中的ASP.NET成员资格提供程序密码 - ASP.NET Membership provider password in email replace 为什么ASP.NET成员资格提供程序未加密我的密码 - Why ASP.NET Membership provider is not Encrypting my password 禁用ASP.NET成员资格提供程序中的密码到期 - Disable password expiration in asp.net membership provider 远程服务器上的ASP.NET成员资格提供程序重置密码失败 - ASP.NET Membership Provider Reset Password Failure on Remote Servers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM