【问题标题】:HMAC SHA1 ColdFusionHMAC SHA1 冷融合
【发布时间】:2011-02-26 22:44:25
【问题描述】:

请帮忙!我一直在拔头发。 :)

我有一个需要 HMAC SHA1 进行身份验证的站点。它目前适用于另一种语言,但现在我需要将其移至 ColdFusion。对于我的生活,我无法让字符串匹配。任何帮助将不胜感激。

数据:https%3A%2F%2Fwww%2Etestwebsite%2Ecom%3Fid%3D5447
密钥:265D5C01D1B4C8FA28DC55C113B4D21005BB2B348859F674977B24E0F37C81B05FAE85FB75EA9CF53ABB9A174C59D98C7A61E2985026D2AA70AE4452A6E3F2F9

正确答案:WJd%2BKxmFxGWdbw4xQJZXd3%2FHkFQ%3d
我的回答:knIVr6wIt6%2Fl7mBJPTTbwQoTIb8%3d

两者都是 Base64 编码,然后是 URL 编码。

【问题讨论】:

  • 最好发布您当前的代码,这将显示您为此使用的功能。

标签: coldfusion sha1 hmac


【解决方案1】:

自己做 HMAC-SHA1 的事情。我能说的最好的就是我找到了这个旧功能。到目前为止,我正在做的事情工作得很好。虽然忘记在哪里找到它,所以我不能相信作者。

对于您的 Base 64 内容...在您的加密上运行此函数,然后对返回的内容执行 cfset newString = toBase64(oldString)。

<cffunction name="hmacEncrypt" returntype="binary" access="public" output="false">
   <cfargument name="signKey" type="string" required="true" />
   <cfargument name="signMessage" type="string" required="true" />
   <cfargument name="algorithm" type="string" default="HmacSHA1" />
   <cfargument name="charset" type="string" default="UTF-8" />

   <cfset var msgBytes = charsetDecode(arguments.signMessage, arguments.charset) />
   <cfset var keyBytes = charsetDecode(arguments.signKey, arguments.charset) />
   <cfset var keySpec = createObject("java","javax.crypto.spec.SecretKeySpec")  />
   <cfset var mac = createObject("java","javax.crypto.Mac") />

   <cfset key = keySpec.init(keyBytes, arguments.algorithm) />
   <cfset mac = mac.getInstance(arguments.algorithm) />
   <cfset mac.init(key) />
   <cfset mac.update(msgBytes) />

   <cfreturn mac.doFinal() />
</cffunction>

【讨论】:

  • 正是我需要的。谢谢。仅供参考:colfdusion 10 内置了一个 hmac() 函数,不是很好:)
【解决方案2】:

输出字符串的较短加密方法(基于Barney's method):

<cffunction name="CFHMAC" output="false" returntype="string">
   <cfargument name="signMsg" type="string" required="true" />
   <cfargument name="signKey" type="string" required="true" />
   <cfargument name="encoding" type="string" default="utf-8" />
   <cfset var key = createObject("java", "javax.crypto.spec.SecretKeySpec").init(signKey.getBytes(arguments.encoding), "HmacSHA1") />
   <cfset var mac = createObject("java", "javax.crypto.Mac").getInstance("HmacSHA1") />
   <cfset mac.init(key) />
   <cfreturn toBase64(mac.doFinal(signMsg.getBytes(arguments.encoding))) />
</cffunction>

另外

  1. ColdFusion 10 支持 HMAC-SHA1 用于本机加密和散列。
  2. 有一个库叫做CF_HMAC distributed by Adobe
  3. 有几个库在为 Amazon 签名文件时处理相关的 HMAC。其中有cf-amazon-s3Barney's S3 URL BuilderRIAForge S3

【讨论】:

  • 不错。请注意String.getBytes(),因为它使用默认编码(并不总是您想要的)。我会将 charset 设为可选参数,默认为 UTF-8。然后将其传递给 charsetDecode 或 getBytes(charset)
  • 仅供参考,由于这篇文章仍然经常出现,修复了 getBytes() 编码问题
【解决方案3】:

史蒂夫 - 感谢您的回复。我实际上已经在使用 hmacEncrypt 函数了。我确实弄清楚了我的问题。我传递的是十六进制键而不是字符串。它接受了密钥,因为从技术上讲它是一个字符串。为了将其恢复为字符串,我使用了另一个函数以及上面的函数。下面的一个将 HEX 更改为字符串。我没有写下面的函数,也不记得它是从哪里获得作者荣誉的,但它工作得很好。

<cffunction name="Hex2Bin" returntype="any" hint="Converts a Hex string to binary">
    <cfargument name="inputString" type="string" required="true" hint="The hexadecimal string to be written.">
    <cfset var outStream = CreateObject("java", "java.io.ByteArrayOutputStream").init()>
    <cfset var inputLength = Len(arguments.inputString)>
    <cfset var outputString = "">
    <cfset var i = 0>
    <cfset var ch = "">
    <cfif inputLength mod 2 neq 0>
    <cfset arguments.inputString = "0" & inputString>
    </cfif>
    <cfloop from="1" to="#inputLength#" index="i" step="2">
        <cfset ch = Mid(inputString, i, 2)>
        <cfset outStream.write(javacast("int", InputBaseN(ch, 16)))>
    </cfloop>
    <cfset outStream.flush()>
    <cfset outStream.close()> 
    <cfreturn outStream.toByteArray()>
</cffunction> 

【讨论】:

  • (这最初是作为答案发布的,但被模组删除了): "Ronald-c 说:我多年前为 CFC 邮件列表上的某个人写了 Hex2Bin!仅供参考,从 CF7 开始,您现在可以这样做:BinaryDecode(inputString, "hex")。因为他们添加了内置函数,所以它更简单(并且性能更高)。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 2011-01-15
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多