C#to Coldfusion for Base64String的翻译

时间:2012-11-14 02:45:35

标签: c# coldfusion base64 azure-storage coldfusion-9

尝试将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)#">

2 个答案:

答案 0 :(得分:1)

C#将结果视为无符号字节,而ColdFusion将它们视为带符号字节。

低于128的值在C#和ColdFusion中都是相同的,而C#中超过128的值在ColdFusion中是负的(two's complement)。

因此,要转换回来,请将256添加到任何负值。

修改

这可能不是BinaryDecode返回的实际字节的问题。在调试期间,ColdFusion如何决定将这些字节打印到屏幕上可能只是一个问题。

比较从C#和ColdFusion获得的实际二进制值(例如,将值保存为二进制文件而不是打印到屏幕上)。

答案 1 :(得分:1)

  

该行取自Azure的创建授权标题;

关于C#和CF / java之间的符号差异,mbeckish是正确的。但是,我不认为内部表示应该对您的最终结果产生任何影响,这通常是您所关心的。通常,您不需要匹配低级整数值,只需匹配base64或hex中字节的字符串表示。只要您以通用格式(如base64)比较最终的HMAC值,它们就应该完全相同。

例如,如果你取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>