2013-05-28 104 views
1

我有一個登錄驗證系統,數據庫中的密碼存儲爲SHA-384。當我包含哈希函數時,下面的登錄腳本什麼也不做。我哪裏錯了?Coldfusion:驗證散列密碼

我使用的是MSSQL Server 2008 R2中,ColdFusion的10

loginform.cfm

<cfif IsDefined("FORM.email")> 
    <cfset redirectLoginSuccess="admin.cfm"> 
    <cfset redirectLoginFailed="login.cfm"> 
    <cfquery name="UserAuth" datasource="sql1007539"> 
    SELECT email,userPass FROM customers WHERE email=<cfqueryparam value="#FORM.email#" cfsqltype="cf_sql_clob" maxlength="255"> 
    AND userPass=<cfqueryparam value="#Hash(form.userPassword, "SHA-384")#" cfsqltype="cf_sql_clob" maxlength="255"> 
    </cfquery> 
    <cfif UserAuth.RecordCount NEQ 0> 
    <cftry> 
     <cflock scope="Session" timeout="30" type="Exclusive"> 
     <cfset Session.Username=FORM.email> 
     <cfset Session.UserAuth=""> 
     </cflock> 
     <cfif IsDefined("URL.accessdenied") AND true> 
     <cfset redirectLoginSuccess=URL.accessdenied> 
     </cfif> 
     <cflocation url="#redirectLoginSuccess#" addtoken="no"> 
     <cfcatch type="Lock"> 
     </cfcatch> 
    </cftry> 
    </cfif> 
    <cflocation url="#redirectLoginFailed#" addtoken="no"> 
    <cfelse> 
    <cfset LoginAction=CGI.SCRIPT_NAME> 
    <cfif CGI.QUERY_STRING NEQ ""> 
    <cfset LoginAction=LoginAction & "?" & XMLFormat(CGI.QUERY_STRING)> 
    </cfif> 
</cfif> 

編輯:如果不使用HASH函數的腳本工作。 編輯:我也可以確認密碼存儲在SHA-384中。我檢查了使用下面的HASH標識符:duncanwinfrey.com/tools/hashid/hash.php

編輯29/05/13

**代碼返回錯誤,當我刪除cfparam標籤**

<cfquery name="UserAuth" datasource="sql1007539"> 
    SELECT email,userPass FROM customers WHERE email="#FORM.email#" 
    AND userPass="#hash(form.userPassword, "sha-384")#" 
    </cfquery> 

返回錯誤 enter image description here

+3

它什麼都不做?你看到了什麼?它是否加載?你可以提交嗎?您是否驗證了參數正在進入服務器頁面?當你說它的工作沒有哈希,這意味着你成功登錄?如果這是原因,那麼您的密碼可能不會在數據庫中散列。檢查你的客戶表:如果你能以純文本的方式讀取密碼,那麼密碼就不會被散列。在查找它們之前調用它們的散列函數將不起作用。如果你想讓它們被散列,你必須計算散列並將其存回表中。 –

+1

您是否嘗試過從數據庫輸出userPass字段,並通過調用hash()密碼的結果進行比較?通常這些問題是由數據保存方式引起的。例如,如果可以使用base64或其他格式。嘗試保存「密碼」的密碼,然後用你在SQL中看到的內容更新你的問題,以及你從CF的散列函數中得到的內容。這可能會給我們一些工作 – barnyr

+0

@Patrick M,如果我使用的形式工作:userPass = 。我可以用一個虛擬賬戶登錄,該賬戶存儲在數據庫中,不需要加密。 –

回答

2

我在專家交流論壇上設法使用(agx)的幫助來工作。事實證明,這是我的錯誤。我在註冊過程的插入查詢中有額外的空間,並且還將編碼設置爲UTF-8:

'(空格)#hash(form.password,「sha-384」,'UTF-8 ')#'

我將密碼類型更改爲char(96),並修改了cfqueryparam,如所建議。謝謝大家的幫助和指導。下面是故障代碼,我曾經幫我想出解決辦法:

進入現有條目的電子郵件地址和密碼,從數據庫中抓取記錄:

<cfset form.email = "some known email"> 
<cfset form.userPassword = "real password before hashing"> 

<!--- ONLY match on email ----> 
<cfquery name="qGetData" ....> 
    SELECT * 
    FROM yourTable 
    WHERE email =<cfqueryparam value='#FORM.email#' 
          cfsqltype="cf_sql_varchar"> 
</cfquery> 

<!--- Checking to see if the password is hashed or is in clear text ---> 
<cfdump var="#qGetData#"> 

散列明文密碼並將其與db值進行比較。

<cfset newhash = hash(form.userPassword,'SHA-384')> 
<cfif compare(newHash, qGetData.userPass) eq 0> 
    SAME 
<cfelse> 
    DIFFERENT 
</cfif> 

乍一看值看起來都一樣。爲了確保無論是在從登錄表單數據庫和密碼存儲的密碼是相同的,使用下面的代碼:

<cfoutput> 
    db |#qGetData.userPass#|<br> 
    form |#hash(form.userPassword,'SHA-384')#|<br> 
</cfoutput> 

然後我用一個handy website to compare the outputs。結果又一次。在所有這些努力工作之後,它變成了在#hash(...)#前面的額外空間。

+0

RE:*結果是一樣的*好工作。儘管有一個更正,如果有一個額外的領先空間,那麼值是不一樣的。該在線工具默認情況下會忽略空白區域,所以除非您更改默認選項,否則您不會看到區別。 – Leigh

+0

我甚至無法計算出在數據庫中出現意想不到的前導空格或尾隨空格,或者更糟的特殊字符從Word的複製/粘貼轉移過來的時候,我已經在牆上敲擊了多少次。 Grrrr ....很高興你把它固定Caludia。 – Shawn

+0

正確。克勞迪婭。 :-) – Shawn

0

不知道這是一個類型0或者這是你的代碼直接拷貝和p如下所示:

您正在使用value屬性的散列函數中的雙引號有效轟炸您的cfquery標記。

  • 你有這樣的:價值= 「#哈希(form.userPassword, 」SHA-384「)#」
  • 這個替換它:值=「#哈希(form.userPassword,「SHA-384 ')#「

請注意圍繞SHA-384值的單引號。這應該可以解決你的問題。

+2

不,對''#do(「this」)#「'完全有效 - 它工作正常並且不會導致任何錯誤。如果你瘋了,你甚至可以做一些像「#」#「#this」#「#」這樣的東西,它仍然可以工作,(即使人眼看起來很棘手)。 –

+0

謝謝您的建議佈雷特,嘗試你的建議後仍然沒有運氣。 –

+0

(ps只是注意到可能觸發了這個響應的問題中的語法着色問題 - 所以爲了澄清,這是SO的語法highligher中的缺陷,它不知道CFML,因此不知道它應該處理散列作爲表達式。) –

2

我會去解決編碼問題。我相信CLOB/BLOB通常是Oracle或DB2數據類型,而不是MS SQL Server本地的。我不認爲您可以將CLOB/BLOB分配爲SQL Server中的數據類型。當您將cf_sql_clob傳遞到cfqueryparam時,它將使用JDBC驅動程序在與SQL Server交談時嘗試轉換爲文本或varchar(max)。翻譯中可能會有某些東西丟失。由於您連接到SQL Server,因此請嘗試將正確的數據類型傳遞給cfqueryparam。查看email和userPass的數據庫列的屬性。您應該可以將cfsqltype設置爲cf_sql_char或cf_sql_varchar。我有點驚訝,查詢沒有拋出錯誤,但錯誤可能被數據類型轉換所掩蓋,並且它不會返回任何結果。

http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6f.html

http://msdn.microsoft.com/en-us/library/ms378813(v=sql.105).aspx

編輯: 試着改變你的查詢:

SELECT email,userPass FROM customers 
WHERE email = <cfqueryparam value="#FORM.email#" cfsqltype="cf_sql_varchar" maxlength="255"> 
AND userPass = <cfqueryparam value="#Hash(form.userPassword, "SHA-384")#" cfsqltype="cf_sql_varchar" maxlength="255"> 
+0

對編輯感到抱歉。它一直在逃避我的cfqueryparams,並且不讓我格式化代碼。 :-S – Shawn

+0

謝謝肖恩,我已經將其付諸行動。 –

+0

這種改變是否奏效? – Shawn

1

當使用雙引號,該值被解析爲一個對象(表,列等)。 始終堅持使用安全快速的cfqueryparam。

嘗試添加第三個參數到強制不同編碼的哈希函數;例如:

<cfquery name="UserAuth" datasource="sql1007539"> 
    SELECT email,userPass FROM customers WHERE email=<cfqueryparam value="#FORM.email#" cfsqltype="cf_sql_clob" maxlength="255"> 
    AND userPass=<cfqueryparam value="#Hash(form.userPassword, "SHA-384", "UTF-8")#" cfsqltype="cf_sql_clob" maxlength="255"> 
    </cfquery> 

請注意UTF-8參數。常見的編碼是:ISO-8859-1,ISO-8859-11(Latin9)。

GI!

+1

我相信CF哈希函數中的編碼參數是錯誤的,並不總是像廣告一樣工作。我知道它曾經是。不知道這是否仍然如此。 – Shawn