2013-05-28 102 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