Coldfusion Hash with SHA-1 vs Php sha1 - hash

I have tried to encrypt the some string using sha-1 in coldfusion 10 and php.
coldfusion code:
<cfsavecontent variable="Mydata">
abcdefghijklmn
</cfsavecontent>
<cfset data = Hash(Mydata,"sha-1") >
<cfdump var="#data#" abort="true"/>
Coldfusion OutPut:
113D1951E36C83FE1F60BF3BC520CEF65E0373BE
PHP code:
$content_digest = sha1('abcdefghijklmn');
var_dump($content_digest);
exit();
PHP OutPut:
85d7c5ff403abe72df5b8a2708821ee33cd0bcce
Both code didn't produce the same output.
And I have tried online tool for SHA-1 http://www.freeformatter.com/sha1-generator.html#ad-output
Site OutPut: 85d7c5ff403abe72df5b8a2708821ee33cd0bcce
That site and php code are produce the same output.
Anyone explain please what is going wrong in my cf code? Thank you.

<cfsavecontent> introduced some extra whitespaces.
So just use
<cfset data = Hash('abcdefghijklmn',"sha-1")>
Run it yourself: http://trycf.com/gist/21e6b5b1ee87f858b913/acf

<cfsavecontent variable="Mydata">
abcdefghijklmn
</cfsavecontent>
<cfset data = Hash(trim(Mydata),"sha-1") >
<cfdump var="#data#" abort="true"/>
Using trim() function I got correct output.
Output: 85D7C5FF403ABE72DF5B8A2708821EE33CD0BCCE

Related

CF11 vs. CF2018 REST 404 Response

I have a REST service that either outputs JSON or returns a 404, depending on whether there's a match. In my existing CF11 setup, I can generate a 404 with
<cfthrow errorcode="404">
but this apparently does not work in CF2018 anymore. In order to generate a 404, I need to use Java (as directed here: How can I send HTTP Status Code and a Response messages to the client in ColdFusion?):
<cfscript>
getPageContext()
.getResponse()
.getResponse()
.sendError( JavaCast( 'int', 404 ), "" );
</cfscript>
This works, but this got me curious, so I created a little test page (not a REST service):
<cfparam name="URL.method" default="cfthrow" >
<cfif URL.method IS "cfthrow">
<cftry>
<cfthrow errorcode="404">
<cfcatch></cfcatch>
</cftry>
</cfif>
<cfif URL.method IS "cfheader">
<cfheader statuscode="404">
</cfif>
<cfif URL.method IS "java">
<cfscript>
getPageContext()
.getResponse()
.getResponse()
.sendError( JavaCast( 'int', 404 ), "" );
</cfscript>
</cfif>
I can't get cfthrow to work here, either. But cfheader DOES work, and as expected, the Java one works, too. Can anyone explain why there are all these disparities? FYI, I'm running Win2012/IIS. Thanks.
p.s. With my existing REST service on CF11, I never could get
<cfheader statuscode="404">
to work, either, to generate a 404. In all cases when I say the 404 doesn't work, what returns is a blank page.

Return multiple data types from a single ColdFusion REST endpoint?

I'm trying to setup a ColdFUsion REST endpoint that can return a file in any number of formats and can return standard error messages but have been running into issues getting that working. For example, a user should be able to send a GET request such as:
https://foo.com/rest/files/123?format=pdf
This would return the file with id 123 in pdf format. And, if the user changed format to txt the same endpoint would return the file in text format. And, if there is no file with id 123, the endpoint would return a 404 error.
The problems I'm running into are twofold:
ColdFusion doesn't seem to give me a way to specify the mime or content type of the file I'm returning and is falling back to whatever is sent in the Accept header sent by the client. This is especially a problem if the client doesn't send that header.
If the client sends an Accept header of application/pdf, I can't get CF to return any error other than a 500 and that's coming from CF, not from me.
The code for my endpoint handler is like this:
<cfcomponent rest="true" restpath="/files/{fileId}" produces="application/json,text/html,application/pdf">
<cffunction name="getFile" access="remote" returnType="any" httpMethod="get">
<!--- query database for file details --->
<cfif qry.RecordCount eq 0>
<cfreturn "404 Not Found" />
<cfelse>
<cfset fileBinary = fileReadBinary(qry.filePath) />
<cfreturn fileBinary />
</cfif>
</cffunction>
</cfcomponent>
Any thoughts? Thanks in advance.

ColdFusion send mail resource not found

I am sending mails in coldfusion as below. But some of my emails being sent are thrown out with the exception below:
<cfif !IsNull(SignatureDetails) && len(trim(SignatureDetails.getDigitalSignature()))>
<!--- Embed digital signature if present via the local file system. --->
<cfset variables.signatureUrl = '../../../urls/files/messages/spreadsheet/rows/columns/' & #SignatureDetails.getDigitalSignature()#>
<cfmailparam file="#ExpandPath('#variables.signatureUrl#')#" contentid="digitalSignature" disposition="inline"/>
</cfif>
And the exception:
object.email.sendTemplateEmail: The resource C:\Data\map\urls\files\messages\spreadsheet\rows\columns\column.jpg was not found. The root cause was: ''.
The correct path should be: C:\Data\urls\files\messages\spreadsheet\rows\columns\column.jpg
The issue is that it is only happening on a select few emails being sent. The directory is hardcoded as above while the name of the signature is pulled from a table in my db.
The problem seems to be the use of relative pathing in this line
<cfset variables.signatureUrl = '../../../urls/files/messages/spreadsheet/rows/columns/' & #SignatureDetails.getDigitalSignature()#>
It is possible that the code is being run from a slightly different directory path depending on the page being executed, as such, going up 3 directories may not give you the path you are looking for. When ColdFusion cannot find a path as you have defined, it appends the know path to the end of the path in which the file being processed exists.
You can correct this by creating a mapping to the signatures (or attachments directory) directory (you define the mapping in Application.cfc) and using this to add the signature.
For mapping pointing to 'signatures' and named 'signatures'
<cfset variables.signatureUrl = '/columns/' & SignatureDetails.getDigitalSignature()>
For mapping pointing to 'attachments' and named 'attachments'
<cfset variables.signatureUrl = '/rows/columns/' & SignatureDetails.getDigitalSignature()>
If you need information about creating mappings in Application.cfc, please check this link.

Coldfusion: authenticating hashed password

I have a login authentication system, the passwords in the database are stored as SHA-384. The following login script does nothing, when I include the Hash function. Where am I going wrong?
I'm using 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>
Edit: The script works if no HASH functions are used.
Edit: I can also confirm the passwords are stored in SHA-384. I checked using the following HASH identifier: duncanwinfrey.com/tools/hashid/hash.php
Edit 29/05/13
**Code returns error, when I remove the cfparam tag **
<cfquery name="UserAuth" datasource="sql1007539">
SELECT email,userPass FROM customers WHERE email="#FORM.email#"
AND userPass="#hash(form.userPassword, "sha-384")#"
</cfquery>
Error returned
I would go with the encoding issue. I believe CLOB/BLOB are typically Oracle or DB2 datatypes and not native to MS SQL Server. I don't think you can assign CLOB/BLOB as a datatype in SQL Server. When you're passing a cf_sql_clob into the cfqueryparam, it's using the JDBC driver to try to convert to text or varchar(max) when it talks back to SQL Server. Something may be getting lost in translation. Since you're connecting to a SQL Server, try passing the correct datatype to the cfqueryparam. Look at the properties of the database columns for email and userPass. You should be able to set the cfsqltype to something like cf_sql_char or cf_sql_varchar. I'm kind of surprised the query isn't throwing an error, but the error may be getting masked by the datatype conversions, and it's simply not returning any results.
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
EDIT:
Try changing your query to:
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">
I managed to get it working with help from (agx) from the Experts Exchange forum. It turns out it was human error on my part. I had an extra space in my insert query of the registration process and also set the encoding to UTF-8:
'(space)#hash(form.password, "sha-384" ,'UTF-8')#'
I changed the password type to char(96), and amended the cfqueryparam, as suggested. Thank you all for your help and guidance. Below is troubleshooting code, I used to help me figure this out:
Entered an email and password of an existing entry, to grab record from the db:
<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#">
Hashed the clear text password and compared it to the db value.
<cfset newhash = hash(form.userPassword,'SHA-384')>
<cfif compare(newHash, qGetData.userPass) eq 0>
SAME
<cfelse>
DIFFERENT
</cfif>
At first sight the values looked the same. To make sure both the stored password in db and password from the login form were the same, the following code was used:
<cfoutput>
db |#qGetData.userPass#|<br>
form |#hash(form.userPassword,'SHA-384')#|<br>
</cfoutput>
I then used a handy website to compare the outputs. The results were the same again. After all this hard work, it turned there was an extra space in front of the #hash(...)#.
When using double quotes, the value is parsed as an object (table, columns, etc).
Always stick with the cfqueryparam, which is secure and fast.
Try adding a third argument to the Hash function which forces a different encoding; eg:
<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>
Note the UTF-8 argument. Common encodings are: ISO-8859-1, ISO-8859-11 (Latin9).
Gl !
Not sure if this is a typeo or this is your code directly copy and pasted:
You are effectively bombing your cfquery tag with the double quotes inside the hash function of the value attribute.
You have this: value="#Hash(form.userPassword, "SHA-384")#"
Replace it with this: value="#Hash(form.userPassword, 'SHA-384')#"
Please note the Single quotes around the SHA-384 value. This should fix your problem.

Hash in coldfusion for secure payment gateway

I am trying to create a hash password in coldfusion for our secure payment gateway to accept a transaction.
Unfortunately the payment gateway is refusing to accept my generated hash.
The form sends through all the elements of the transaction and sends a generated hash based on five different fields.
In PHP it is-:
<?php
echo hash('sha256', '
test_site1234
GBP
OrderTotal
OrderID
PASSWORD
');;
?>
Am I right in thinking the code in coldfusion should be -:
<cfset sitesecurity = Hash("test_site1234"&"GBP"&#OrderTotal#&#URL.ThisOrderID#&"PASSWORD", "SHA-256")>
<cfoutput>#sitesecurity#</cfoutput>
I believe the link Miguel-F posted will fix your issue. Coldfusion's hash output is in all uppercase where most (all?) other outputs I've seen are in lowercase. Depending on how your gateway handles case sensitivity you should try passing a lowercase hash.
<cfset sitesecurity = lCase(hash("test_site1234GBP"&OrderTotal&URL.ThisOrderID&"PASSWORD", "SHA-256"))>
The code should have functioned the way it is, but in my opinion it's better to create the value to hash as one big string. Appending to strings is 'costly' because each time you add to a string a new string is created and the old one destroyed. If you're processing one transaction a minute you'd never notice a difference, but it is good practice either way. I would use.
<cfset sitesecurity = Hash("test_site1234GBP#OrderTotal##URL.ThisOrderID#PASSWORD", "SHA-256")>
Now you may have an issue getting a HASH in PHP to match a HASH in ColdFusion, but that's a separate issue.
Sample
<cfset OrderTotal = 10>
<cfset url.ThisOrderID = 50>
<cfset sitesecurity = Hash("test_site1234GBP#OrderTotal##URL.ThisOrderID#PASSWORD", "SHA-256")>
<cfdump var="#sitesecurity#" abort>
Returns
92A14E1D03833CB3FD6932A8E240861CDEC66E46723A544DFBC3C592D5EE7E66