ColdFusion哈希

7
我正在尝试使用这个公式创建密码摘要来获得以下变量,但是我的代码与正确答案不匹配。我不确定我做错了什么,但我会承认我需要帮助。希望有人能提供帮助。
公式如下: Base64(SHA1(NONCE + TIMESTAMP + SHA1(PASSWORD)))
正确的密码摘要答案是:+LzcaRc+ndGAcZIXmq/N7xGes+k=
ColdFusion 代码:
<cfSet PW = "AMADEUS">
<cfSet TS = "2015-09-30T14:12:15Z">
<cfSet NONCE = "secretnonce10111"> 
<cfDump var="#ToBase64(Hash(NONCE & TS & Hash(PW,'SHA-1'),'SHA-1'))#">

我的代码输出:

Njk0MEY3MDc0NUYyOEE1MDMwRURGRkNGNTVGOTcyMUI4OUMxM0U0Qg==

我明显做错了什么,但是就算拼命想也想不出来。有人知道吗?


你能否发布文档链接? - Leigh
文档不在公共链接中可用 :( - Jill Plotke
糟糕。有任何可以发布的例子或片段吗?即使是用其他语言编写的,比如说Java / C#或PHP?我知道问题的原因,并且有针对这种特定情况的解决方案。但是,他们的说明存在一些歧义,因此我希望确保解决方案在所有情况下都有效。 - Leigh
1
@Alex - 你为什么这么说?在CF中它可以很好地解码。 - Leigh
1
我不知道你保护的是什么类型的网站,或者你需要多高的安全性,但只是作为参考:https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet - Shawn
1个回答

6
哈希的有趣之处在于,即使您从正确的字符串开始,如果这些字符串被错误地组合/编码/解码,结果仍然可能完全错误。
最大的陷阱是,大多数哈希函数实际上使用输入字符串的二进制表示。因此,如何解码这些字符串会产生很大的差异。注意,当作为UTF-8和十六进制进行解码时,相同的字符串会产生完全不同的二进制?这意味着哈希、ToBase64等的结果也将完全不同。
// Result: UTF-8: 65-65-68-69
writeOutput("<br>UTF-8: "& arrayToList(charsetDecode("AADE", "UTF-8"), "-"));

// Result:  HEX: -86--34
writeOutput("<br>HEX: "& arrayToList(binaryDecode("AADE", "HEX"), "-"));

可能的解决方案:

当前代码的问题在于 ToBase64假定输入字符串已经编码为UTF-8。而 Hash()实际上返回一个十六进制字符串。因此ToBase64()会错误地解码它。相反,使用 binaryDecode binaryEncode将哈希从十六进制转换为base64:

resultAsHex = Hash( NONCE & TS & Hash(PW,"SHA-1"), "SHA-1");
resultAsBase64 = binaryEncode(binaryDecode(resultAsHex, "HEX"), "base64");
writeDump(resultAsBase64);

更为健壮的解决方案:

话虽如此,但字符串拼接和哈希处理要非常小心。因为它并不总是产生预期结果。如果没有更多关于这个特定API的了解,我无法完全确定它所期望的内容。然而,通常只使用二进制值会更安全。不幸的是,CF的ArrayAppend()函数不支持二进制数组,但你可以轻松地使用Apache's ArrayUtils类,它与CF捆绑在一起。

ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");

// Combine binary of NONCE + TS
nonceBytes = charsetDecode(NONCE, "UTF-8");
timeBytes = charsetDecode(TS, "UTF-8");
combinedBytes = ArrayUtils.addAll(nonceBytes, timeBytes);

// Combine with binary of SECRET 
secretBytes = binaryDecode( Hash(PW,"SHA-1"), "HEX");
combinedBytes = ArrayUtils.addAll(combinedBytes, secretBytes);

// Finally, HASH the binary and convert to base64
resultAsHex = hash(combinedBytes, "SHA-1");
resultAsBase64 = binaryEncode(binaryDecode(resultAsHex, "hex"), "base64");

writeDump(resultAsBase64);

非常感谢!这非常有帮助 :) - Jill Plotke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接