尝试将C#代码转换为CF并且即时翻译以下行
StorageKey = 'abcd';
Convert.FromBase64String(StorageKey)
上面的行产生一个105,183,29的字节数组
该行取自Azure的创建授权标题;
System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(StorageKey));
我在msdn库上查找了FromBase64String方法,但它超出了我的想象。我希望有人可以指出我正确的Coldfusion方向。
我已经尝试了BinaryDecode(StorageKey,“BASE64”),对我来说这似乎是最合乎逻辑的翻译,但我回到了105-7329,这不是我预期的结果。
请参阅下面的Leigh对CF10 +的回答,如果您正在使用CF7-9解决方案这是我的尝试
var javaMsg = javacast("string", arguments.sigMsg).getBytes("UTF-8");
var javaKey = JavaCast("string", arguments.sigKey);
var myKey = createObject('java', 'javax.crypto.spec.SecretKeySpec' );
var mac = createObject('java', "javax.crypto.Mac");
var myKeyB64 = CreateObject("java", "org.apache.commons.codec.binary.Base64").decodeBase64(javaKey.getBytes());
var secret = myKey.Init(myKeyB64, 'HmacSHA256');
mac = mac.getInstance("HmacSHA256");
mac.init(secret);
</cfscript>
<cfdump var="#mac.doFinal(javaMsg)#">
答案 0 :(得分:1)
C#将结果视为无符号字节,而ColdFusion将它们视为带符号字节。
低于128的值在C#和ColdFusion中都是相同的,而C#中超过128的值在ColdFusion中是负的(two's complement)。
因此,要转换回来,请将256添加到任何负值。
修改强>
这可能不是BinaryDecode返回的实际字节的问题。在调试期间,ColdFusion如何决定将这些字节打印到屏幕上可能只是一个问题。
比较从C#和ColdFusion获得的实际二进制值(例如,将值保存为二进制文件而不是打印到屏幕上)。
答案 1 :(得分:1)
关于C#和CF / java之间的符号差异,mbeckish是正确的。但是,我不认为内部表示应该对您的最终结果产生任何影响,这通常是您所关心的。通常,您不需要匹配低级整数值,只需匹配base64或hex中字节的字符串表示。只要您以通用格式(如base64)比较最终的HMAC值,它们就应该完全相同。该行取自Azure的创建授权标题;
例如,如果你取sample signature string here,则CF10和C#都返回相同的值。所以看起来你的问题可能就是别的了。
<cfscript>
savecontent variable="signatureString" {
WriteOutput("GET#chr(10)##chr(10)##chr(10)##chr(10)#x-ms-date:Mon, 01 Dec 2008 05:17:57 GMT#chr(10)#/accountname/queuename/messages");
};
key = binaryDecode("abcd", "base64");
resultInHex = hmac(signatureString, key,"HMACSHA256");
// result: wxR7Bt6sWEKVJ9vEjCiuqA8OKCZOKYfbxaXj85whOkM=
WriteDump(binaryEncode(binaryDecode(resultInHex, "hex"), "base64"));
</cfscript>
编辑:我知道有一堆CF10之前的hmac功能浮出水面。但他们中的许多人都忘了编码。这是一个通用的改编版,它接受一种算法(“hmacsha256”,“hmacsha1”,..)和编码(“utf-8”)。它应与CF7-9一起使用。
<cfset result = hmacX( signatureString, "abcd", "HmacSHA256") />
<cfdump var="#result#" />
<cffunction name="hmacX" returntype="string" hint="">
<cfargument name="message" type="string" required="true" />
<cfargument name="keyInBase64" type="any" required="true" />
<cfargument name="algorithm" type="string" default="HmacSHA256" />
<cfargument name="encoding" type="string" default="UTF-8" />
<cfset var dataBytes = charsetDecode( arguments.message, arguments.encoding ) />
<cfset var keyBytes = binaryDecode( arguments.keyInBase64, "base64" ) />
<cfset var keySpec = createObject("java", "javax.crypto.spec.SecretKeySpec") />
<cfset var secret = keySpec.init( keyBytes, arguments.algorithm ) />
<cfset var mac = createObject("java", "javax.crypto.Mac").getInstance( arguments.algorithm ) />
<cfset mac.init( secret ) />
<cfreturn binaryEncode( mac.doFinal(dataBytes), "base64") />
</cffunction>