【问题标题】:ColdFusion Hash冷融合散列
【发布时间】:2017-05-18 22:48:40
【问题描述】:

我正在尝试使用此公式创建密码摘要以获取以下变量,但我的代码不匹配。不知道我做错了什么,但是当我需要帮助时我会承认。希望有人可以提供帮助。

  • 文档中的公式: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==

我显然做错了什么,但我一生都无法弄清楚是什么。任何人?比勒?

【问题讨论】:

  • 您可以发布文档链接吗?
  • 该文档在公共链接中不可用:(
  • 无赖。任何“可发布”示例或 sn-ps - 即使是另一种语言,例如 java/c# 或 php?我看到了导致问题的原因,并为这种特定情况提供了解决方案。但是,他们的说明有些含糊不清,所以我想确保该解决方案适用于所有情况。
  • @Alex - 你为什么这么说?它在 CF 中解码良好。
  • 我不知道您要保护哪种类型的网站或您需要它的安全性,但仅供参考:owasp.org/index.php/Password_Storage_Cheat_Sheet

标签: hash coldfusion sha1 coldfusion-10 amadeus


【解决方案1】:

散列的有趣之处在于,即使您从正确的字符串开始,如果这些字符串组合/编码/解码不正确,结果仍然可能完全错误。

最大的问题是这些函数中的大多数实际上都使用输入字符串的二进制表示。因此,如何解码这些字符串会产生很大的不同。请注意,当解码为 UTF-8 与 Hex 时,相同的字符串会产生完全不同的二进制文件?这意味着 Hash、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() 解码不正确。相反,使用binaryDecodebinaryEncode 将哈希从十六进制转换为base64:

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

更强大的解决方案:

话虽如此,但要非常小心字符串连接和散列。作为it does not always yield the expected results。如果不了解更多关于这个特定 API 的信息,我无法完全确定它的预期。但是,仅使用二进制值通常更安全。不幸的是,CF 的 ArrayAppend() 函数缺乏对二进制数组的支持,但您可以轻松地使用与 CF 捆绑在一起的Apache's ArrayUtils 类。

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);

【讨论】:

  • 非常感谢!这非常有帮助:)
  • 很高兴它有帮助。 (......第一个问题很好。欢迎来到 S.O. :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 2011-01-15
  • 1970-01-01
相关资源
最近更新 更多