2012-11-11 25 views
3

我在我的應用程序中使用PBKDF2來存儲用戶密碼。在我的用戶表,我這是這樣確定的SaltPassword柱:從表列讀取二進制到字節[] array

// Hash the users password using PBKDF2 
var DeriveBytes = new Rfc2898DeriveBytes(_Password, 20); 
byte[] _Salt = DeriveBytes.Salt; 
byte[] _Key = DeriveBytes.GetBytes(20); // _Key is put into the Password column 

在我的登錄頁面,我需要找回這種鹽和密碼。因爲它們是byte []數組,我將它們作爲varbinary(MAX)存儲在我的表中。現在我需要檢索它們以與用戶輸入的密碼進行比較。我將如何使用SqlDataReader來做到這一點?目前我有這樣的:

cn.Open(); 
SqlCommand Command = new SqlCommand("SELECT Salt, Password FROM Users WHERE Email = @Email", cn); 
Command.Parameters.Add("@Email", SqlDbType.NVarChar).Value = _Email; 
SqlDataReader Reader = Command.ExecuteReader(CommandBehavior.CloseConnection); 
Reader.Read(); 
if (Reader.HasRows) 
{ 
    // This user exists, check their password with the one entered 
    byte[] _Salt = Reader.GetBytes(0, 0, _Salt, 0, _Salt.Length); 
} 
else 
{ 
    // No user with this email exists 
    Feedback.Text = "No user with this email exists, check for typos or register"; 
} 

但我知道一個事實,那是錯的。 Reader中的其他方法只有一個參數是要檢索的列的索引。

謝謝!

+0

正是你怎麼知道它錯了嗎?因爲你正在做所有其他相關問題正在做的事情。你確定你創建的字節數組可以放在'varbyte'中嗎 –

+0

VS拋出一個錯誤,說它不能將long轉換爲byte [],並且參數描述與我放入的不一樣,比如'Salt ._Length'。 –

回答

6

直接澆鑄成byte[]迄今已爲我工作。

using (SqlConnection c = new SqlConnection("FOO")) 
{ 
    c.Open(); 
    String sql = @" 
     SELECT Salt, Password 
     FROM Users 
     WHERE (Email = @Email)"; 
    using (SqlCommand cmd = new SqlCommand(sql, c)) 
    { 
     cmd.Parameters.Add("@Email", SqlDbType.NVarChar).Value = _Email; 
     using (SqlDataReader d = cmd.ExecuteReader()) 
     { 
      if (d.Read()) 
      { 
       byte[] salt = (byte[])d["Salt"]; 
       byte[] pass = (byte[])d["Password"]; 

       //Do stuff with salt and pass 
      } 
      else 
      { 
       // NO User with email exists 
      } 
     } 
    } 
} 
1

我不確定你爲什麼認爲你寫的代碼是錯誤的(請說明)。但專門爲該錯誤:
請注意,GetBytes返回一個long不是一個字節數組。

所以,你應該使用: Reader.GetBytes(0, 0, _Salt, 0, _Salt.Length);


long bytesRead = Reader.GetBytes(0, 0, _Salt, 0, _Salt.Length);

+0

如果您查看該方法所需的參數,則可以看到我的參數不正確,但我不知道要指定什麼。而且我不能將它轉換爲很長的時間,它必須作爲一個字節數組返回,以便我的密碼檢查工作。 –

+1

@JamesDawson請閱讀GetBytes函數(我在我的回答中發佈)的描述:***從給定緩衝區偏移量***開始,從指定的列偏移量中讀取一個字節流到緩衝區中的一個數組。換句話說,在你的例子中,將列號爲0的字節流複製到'_Salt'變量中。這正是你要求的。 (GetBytes函數的返回值只是讀取的字節數,因此它是一個'long')。你是否按照我的建議更改了代碼?它有用嗎? – Blachshma