2010-12-16 141 views
2

我需要執行此SQL命令(Management Studio中正常工作):LinqToSql和HASHBYTES

select * from Users where Login = 'test' and PasswordHash = HashBytes('SHA1', 'test') 

我寫這個C#linqtosql:

var user = db.ExecuteQuery<User>("select * from Users where Login = {0} and PasswordHash = HashBytes('SHA1', {1})", loginTextBox.Text.Trim(), passwordPasswordBox.Password).SingleOrDefault(); 

,但它永遠不會奏效!

有人可以幫我嗎?

謝謝!

這是DataContext的日誌:

select * from Users where Login = @p0 and PasswordHash = HashBytes('SHA1', @p1) 
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [test] 
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [test] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 
+0

回報總是空 – 2010-12-16 19:35:58

+0

不論答案是什麼,我會將此轉換爲參數化查詢,否則你會把自己暴露給SQL注入攻擊。 – 2010-12-16 19:55:40

+2

我不這麼認爲,因爲ExecuteQuery將任何{x}轉換爲@ p1,@ p2等... – 2010-12-16 19:59:55

回答

4

我通過db.Log = Console.Out異形它,結果:

-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 

select * from Users where Login = @p0 and PasswordHash = HashBytes('SHA1', @p1) 
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Admiral Trask] 
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Arutha] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 

見到這種情景,我想象的問題是,參數是NVarChar而非varchar - 所以服用的散列(一二進制操作)是不同的。如果你散列它作爲varchar,你應該把字符串投到varchar之前HASHBYTES

下面的作品,例如:

var user = db.ExecuteQuery<User>(@"select * from Users where Login = {0} 
     and PasswordHash = HashBytes('SHA1', CAST({1} as varchar(40)))", cn, pw) 
     .SingleOrDefault(); 

這方面的一個簡單的例證是:

SELECT HASHBYTES('SHA1','12345'), HASHBYTES('SHA1',N'12345') 
+0

我們去=)謝謝! – 2010-12-16 20:32:33

0

看來你錯過了模板字符串報價登錄名和密碼。

var user = db.ExecuteQuery<User>("select * from Users where Login = '{0}' and PasswordHash = HashBytes('SHA1', '{1}')", loginTextBox.Text.Trim(), passwordPasswordBox.Password).SingleOrDefault(); 
+0

我試過了,也不管用... – 2010-12-16 19:46:05

+0

'select * from Users'SQL命令返回任何C# ? – Anton 2010-12-16 19:52:40

+0

是的,它的工作原理,即使我添加登錄= ...問題是與hashbytes ... – 2010-12-16 19:54:48

2

你真的想要做的是一個C#方法映射到數據庫功能HASHBYTES,這是這樣做的

[Function(Name = "HashBytes")] 
[return: Parameter(DbType = "VarChar(100)")] 
string HashBytes(string hashtype, string text) 
{ .... } 

詳細信息在這裏給出:http://msdn.microsoft.com/en-us/library/bb386973.aspx

這將允許你寫不出像樣LINQ查詢:

var q = from u in db.Users 
     where u.Login == cn && u.PasswordHash == HashBytes("SHA1", pw) 
     select u; 
+0

HashBytes不返回varchar,並不限於100,而且恰巧它仍然不能「按原樣」工作,因爲它仍然會將'text'視爲'nvarchar',從而給出OP的錯誤結果需要。 – 2010-12-16 20:36:39

+1

這適用於我: [函數(Name =「HASHBYTES」,IsComposable = true)] public byte [] HashBytes(string algorithm,Binary input){} – TomZ 2011-01-05 22:17:59