按钮单击时将二进制转换为varchar

时间:2014-01-23 01:06:29

标签: asp.net sql sql-server visual-studio

我正在尝试为SQL服务器创建一个注册页面,但在登录部分时我遇到了一些问题。密码短语列设置为dataType Binary(20)。当用户从我的表单中注册帐户时,它会在密码短语列中输入密码。

insertUser.Parameters.AddWithValue("@Passphrase", System.Text.Encoding.Default.GetBytes(TextBoxPass.Text));

当我使用创建帐户的默认存储过程创建密码时,它会将密码短语列中的密码设置为“NULL”。

ALTER FUNCTION [dbo].[FN_HashPassphrase2](
@vchPassphrase varchar(12),
@intAccountID int
)
RETURNS binary(20)
AS
BEGIN
RETURN (
    HASHBYTES('md5',@vchPassphrase)
);
END

当我尝试登录使用注册页面创建的帐户时,我得到密码不匹配。

我的问题是......

当有人在登录字段中输入他们的帐户信息时,如何在点击登录按钮时将其转换为varchar(12)?

这是我点击按钮

protected void Button1_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["RegDNMembershipConnectionString"].ConnectionString);
    con.Open();
    string cmdStr = "select count(*) from Accounts where AccountName='" + TextBox1.Text + "'";
    SqlCommand Checkuser = new SqlCommand(cmdStr, con);
    int temp = Convert.ToInt32(Checkuser.ExecuteScalar().ToString());
    if (temp == 1)
    {
        string cmdStr2="Select Passphrase from Accounts where AccountName='" + TextBox1.Text + "'";
        SqlCommand pass=new SqlCommand(cmdStr2, con);
        string password=pass.ExecuteScalar().ToString();
        con.Close();

1 个答案:

答案 0 :(得分:0)

要回答这个问题,因为您没有显示将密码与用户输入的文本进行比较的实际代码。我假设您正在尝试将无效数据相互比较。值得注意的是,比较二进制将是Case Sensitive。 (是的,我知道二进制文件对二进制内容没有任何区分大小写的概念)。

我将采取的过程(如果我必须使用此示例)使用SP创建用户帐户并使用您现有的函数设置二进制密码。 (请注意,这是非常基本的,并且无法检查帐户是否已存在)。

CREATE PROCEDURE [dbo].[sp_CreateUser]
    @AccountName nvarchar(50),
    @Passphrase nvarchar(50)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Passbinary binary(20) = (SELECT [dbo].[FN_HashPassphrase2](@Passphrase))
    INSERT INTO [dbo].[Accounts] (AccountName, Passphrase) VALUES (@AccountName, @Passbinary)
END

然后在表单上创建用户,例如......

using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["CON_String"].ConnectionString))
{
    var cmd = new SqlCommand("EXEC sp_CreateUser @p0, @p1", con);
    cmd.Parameters.AddWithValue("@p0", Username.Text);
    cmd.Parameters.AddWithValue("@p1", Password.Text);
    con.Open();
    cmd.ExecuteNonQuery();
    con.Close();
}

现在,这给了我们一个结果,如(是基本的)。 enter image description here

所以我们现在在数据库中拥有正确的数据。现在,为了检查用户帐户,我将使用另一个存储过程,使用您现有的散列函数传递AccountNamePasspharse的纯文本来比较密码二进制字符串,例如。

ALTER PROCEDURE sp_VerifyUser
    @AccountName nvarchar(50),
    @Passphrase nvarchar(50)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Passbinary binary(20) = (SELECT [dbo].[FN_HashPassphrase2](@Passphrase))
    DECLARE @AccountID int = (SELECT TOP 1 AccountID FROM [dbo].[Accounts] WHERE AccountName = @AccountName AND Passphrase = @Passbinary)
    SELECT TOP 1 CAST(CASE WHEN @AccountID IS NULL THEN -1 ELSE @AccountID END as INT)
END
GO

如果用户存在,这个简单的SP将返回一个int(帐号),方法是匹配帐户名和二进制转换后的密码。如果没有匹配,则返回-1,否则将返回accountID。然后从你的代码中,这很容易调用,如。

errorLbl.Text = "";
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["CON_String"].ConnectionString))
{
    var cmd = new SqlCommand("EXEC sp_VerifyUser @p0, @p1", con);
    cmd.Parameters.AddWithValue("@p0", Username.Text);
    cmd.Parameters.AddWithValue("@p1", Password.Text);
    con.Open();
    var accountID = (int)cmd.ExecuteScalar();
    con.Close();
    if (accountID == -1)
        errorLbl.Text = "Username and password mismatch";
    else
    {
        errorLbl.Text = "YOUR GOOD TO GO! Have a nice day.. Your account ID is:" + accountID;
    }
}

正如您所看到的,这是一个非常简单的例子。

这将做什么

  1. 使用MD5哈希函数二进制存储密码
  2. 将用户纯文本用户名和密码与调用上面相同哈希函数的存储记录进行比较
  3. 缺少什么

    1. 未考虑您的所有其他帐户字段
    2. 不代表您的实际数据库架构。