我试图模仿这个PHP功能
<?php
base64_encode( hash_hmac( 'SHA256', $a, $b, true) );
?>
"HmacSHA256"和"sha256"有区别吗?
这有效 - 但不会给我相同的结果:
<cfscript>
toBase64( hmac( a, b, 'HmacSHA256', 'us-ascii' ) );
</cfscript>
这告诉我"SHA256"无用(因为我不使用企业版)
<cfscript>
toBase64( hmac( a, b, 'SHA256', 'us-ascii' ) );
</cfscript>
有什么方法可以在没有企业的情况下做到这一点吗? 难道没有一个我可以绑定的 Java 库进行编码吗?
谢谢
hmac
的 CF 文档非常缺乏有用的细节。代码不起作用的原因是hmac()
返回十六进制字符串。而 PHP 对hash-hmac
的调用返回二进制。因此,您的 CF 脚本采用 base64 编码完全不同的值。这就是为什么两个结果不匹配的原因。
您需要先将十六进制字符串解码为二进制。然后将二进制文件编码为 base64,结果将匹配:
resultAsHex = hmac("Well done is better than well said.", "key", "HmacSHA256");
finalValue = binaryEncode( binaryDecode(resultAsHex, "hex"), "base64" );
writeDump( finalValue );
顺便说一句,toBase64()
已被弃用。文档建议将binaryEncode
用于新应用程序。
最近使用的东西的通用版本。还没有测试过这个确切的代码,但试一试。我将SECRET_KEY
的加密值存储在数据库中,以便将其排除在应用程序代码之外。
<cffunction name="HmacSHA256" access="public" output="false" returntype="string" hint="Generates HmacSHA256 string.">
<cfargument name="message" type="string" required="true" hint="form data" />
<cfset var HMAC_SHA256 = "HmacSHA256" />
<cfset var SECRET_KEY = "{YOUR_SECRET_KEY}" />
<cfset var secretKeySpec = createObject("java", "javax.crypto.spec.SecretKeySpec").init( SECRET_KEY.getBytes("UTF-8"), HMAC_SHA256 ) />
<cfset var mac = createObject("java", "javax.crypto.Mac").getInstance(HMAC_SHA256) />
<cfset mac.init( secretKeySpec ) />
<cfset var rawHmac = mac.doFinal( arguments.message.getBytes("UTF-8") ) />
<cfset var encoder = createObject("java", "sun.misc.BASE64Encoder") />
<cfreturn encoder.encodeBuffer(rawHmac).replace("n", "").replace("r", "") />
</cffunction>
看起来您可能需要安装库才能获得sha256
ColdFusion 10 引入了 hmac() 函数,用于生成安全的散列消息身份验证码 (HMAC)。此功能使处理第三方 API 变得更加容易。但是,在 ColdFusion 10 之前,您需要深入 Java 层才能访问安全库。这个 ColdFusion 组件 - Crypto.cfc - 试图使访问这些库更容易、更简洁。