我有一个登录验证系统,数据库中的密码存储为SHA-384。当我包含Hash函数时,以下登录脚本不执行任何操作。我哪里错了?
我正在使用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>
错误返回
答案 0 :(得分:2)
我会考虑编码问题。我相信CLOB / BLOB通常是Oracle或DB2数据类型,而不是MS SQL Server的本机。我认为您不能在SQL Server中将CLOB / BLOB指定为数据类型。当您将cf_sql_clob传递给cfqueryparam时,它正在使用JDBC驱动程序在它回退到SQL Server时尝试转换为text或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">
答案 1 :(得分: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>
乍一看,价值看起来一样。为了确保db中存储的密码和登录表单中的密码相同,使用了以下代码:
<cfoutput>
db |#qGetData.userPass#|<br>
form |#hash(form.userPassword,'SHA-384')#|<br>
</cfoutput>
然后我使用了handy website to compare the outputs。结果再次相同。经过所有这些艰苦的工作后,它变成了#hash(...)#
前面有一个额外的空间。
答案 2 :(得分:1)
使用双引号时,该值将被解析为对象(表,列等)。 始终坚持使用cfqueryparam,这是安全和快速的。
尝试向Hash函数添加第三个参数,强制执行不同的编码;例如:
<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)。
Gl!
答案 3 :(得分:0)
不确定这是否是一个typeo,或者这是你的代码直接复制和粘贴:
您实际上是使用value属性的哈希函数中的双引号来轰炸您的cfquery标记。
请注意SHA-384值周围的单引号。这应该可以解决你的问题。