我已经看到很多Coldfusion Decrypt功能的问题和解决方案。但是,我根本没有遇到过这个。
我可以正确加密和解密。我生成了一个密钥并使用以下方法加密:
<cfset encrytedpwd = encrypt(password, mykey, "AES/CBC/PKCS5Padding", "hex")>
这是在程序#1中完成的。然后在另一个程序#2中,我用:
解密它<cfset mypwd = decrypt(encrytedpwd, mykey, AES/CBC/PKCS5Padding", "hex")>
这很棒,效果很好。
现在问题是:所有记录的密码并不总是加密的。有些是加密的,因为它们通过了#1程序。但是有些旧记录没有加密。因此,当密码被检索为&#34; encrytedpwd&#34;时,解密函数将因错误而崩溃:
尝试加密或解密输入字符串时出错:&#39;&#39;&#39;。
我希望CF Decrypt函数可以返回&#34; false&#34;或某种警告,而不是导致CF崩溃。
另一种情况是,如果有人在传递给程序#2之前使用加密密码的值进行调整,它也会崩溃。
有没有办法在传递给Decrypt函数之前检查密码的值是否为十六进制,以便它不会失败?
非常感谢。
编辑:
我在代码中添加了try / catch,它根本没有捕获异常。
在CF activate.cfm的顶部,我包含一个模板调用handlerror.cfm,其中包含以下内容:
<cferror
template = "exception.cfm"
type = "exception"
mailTo = "webmaster@mydomain.com">
exception.cfm只是一个格式化的错误页面:
...
<li><b>Your Location:</b> #error.remoteAddress#
<li><b>Your Browser:</b> #error.browser#
<li><b>Date and Time the Error Occurred:</b> #error.dateTime#
<li><b>Page You Came From:</b> #error.HTTPReferer#
<li><b>Message Content</b>:
<p>#error.diagnostics#</p>
...
activate.cfm有
<cfinclude template="handlerror.cfm">
<cfif isdefined("url.chk") and isdefined("url.auth")>
<cfif len(url.chk) gt 0 and len(url.auth) gt 0>
<cftry>
<cfset uid=decrypt(url.chk, mykey, "AES/CBC/PKCS5Padding", "hex")>
<cfcatch>
<div class="msgcenter">
<div class="warning">Sorry, there seems to be an issue with the activation </div><br>
</div>
<cfoutput>
<!--- The diagnostic message from ColdFusion. --->
<p>#cfcatch.message#</p>
<p>Caught an exception, type = #CFCATCH.TYPE#</p>
<p>The contents of the tag stack are:</p>
<cfdump var="#cfcatch.tagcontext#">
</cfoutput>
</cfcatch>
</cftry>
<cfif REFindNoCase("[^a-z0-9_]", uid)>
<div class="warning">Problem with User ID.</div><br>
<cfelse>
.....
所以现在发生的事情是,如果url.chk被调节或无效,它将显示异常,但是对于REFindNoCase的未定义UID,因为Decrypt首先没有工作,现在它是因为try / catch而跳过它。
如果没有try / catch,异常会显示错误消息&#34; 尝试加密或解密输入字符串时出错:&#39;&#39;。&# 34;但由于try / catch,它现在没有这样做。所以我被卡住了。
答案 0 :(得分:1)
在tryo / catch块中包含在Railo和CF中为我工作。我看到您正在使用<cferror>
页面,但如果确实存在干扰,您可以在应用程序外部运行此代码,以便try / catch将参与或暂时禁用该错误。
由于你的CFERROR,我会在你的桌子上运行一个脚本,如下所示,用一个标志字段更新未加密的用户。然后你可以
代码:
<cfset PlainPWsList = "">
<cfoutput><cfloop query="CheckPWs">
encrypted password: #i#<br/>
<cftry><cfset AttemptDecrypt = Decrypt(password...)>
<cfcatch type="any"><cfset PlainPWsList = ListAppend(PlainPWsList,userID)><!--- This password wasn't encrypted ---></cfcatch></cftry><br><br>
</cfloop>
</cfoutput>
<cfquery>
update users
set forcepwchange = 1
where userID in (<cfqueryparam cfsqltype="cf_sql_integer" value="#PlainPWsList#" list="yes">)
</cfquery>
然后,当用户登录时,您可以根据标志的值做出决定。你甚至可以在查询中完全这样做。
select userid,stuff from users
where username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.username#">
and ((password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#encrypt(form.password)#"> and forcepwchange = 0) or (password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.password#"> and forcepwchange = 1))
现在,正如Leigh提出的那样:为什么你没有哈希密码?。唯一几乎合理的&#34;使用&#34;因为没有哈希你的密码是密码恢复,真的,允许用户重置路由更好。加密/解密否则只允许工作人员或窥探看到密码。即使您设计了一个管理员可以登录用户帐户以进行客户服务的系统,也可以编写辅助网关,以便管理员不需要知道用户密码。
这就是我要做的事情......我已经加强了旗帜。
0 =密码已经哈希并且很好。虽然盐渍哈希是一件好事,但是没有必要加密然后哈希。在任何列表中的用户到达的更改密码页面上,我只是对数据进行加密和哈希处理。盐,因为有整个词典的直接哈希表(并且给予人们对最简单的密码的倾向,这对于帮助他们避免这很重要。)
1 =密码已加密且需要散列。
2 =密码是纯文本,需要散列。
<cfset PlainPWsList = "">
<cfset EncryptedPWsList = "">
<cfoutput><cfloop query="CheckPWs">
encrypted password: #i#<br/>
<cftry><cfset AttemptDecrypt = Decrypt(password...)>
<cfset EncryptedPWsList=ListAppend(EncryptedPWsList,userID)>
<cfcatch type="any"><cfset PlainPWsList = ListAppend(PlainPWsList,userID)><!--- This password wasn't encrypted ---></cfcatch></cftry><br><br>
</cfloop>
</cfoutput>
<cfquery>
update users
set forcepwchange = 2
where userID in (<cfqueryparam cfsqltype="cf_sql_integer" value="#PlainPWsList#" list="yes">)
</cfquery>
<cfquery>
update users
set forcepwchange = 1
where userID in (<cfqueryparam cfsqltype="cf_sql_integer" value="#EncryptedPWsList#" list="yes">)
</cfquery>
然后是您的登录查询
select userid,stuff from users
where username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.username#">
and ((password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#hash(saltedpassword)#"> and forcepwchange = 0)
or (password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#encrypt(form.password)#"> and forcepwchange = 1)
or (password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.password#"> and forcepwchange = 2))