1

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が返されました。

CF10 +については、以下のLeighの回答を参照してください。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)#">
4

2 に答える 2

1

この行は、Azure の認証ヘッダーの作成から取られています。

C# と CF/java の符号の違いについては mbeckish が正しいです。ただし、内部表現が最終結果に影響を与えるべきではないと思います。通常、それはあなたが気にするすべてです。通常、低レベルの整数値を一致させる必要はなく、base64 または 16 進数でのバイトの文字列表現のみを一致させる必要があります。最終的な HMAC 値を base64 などの一般的な形式で比較する限り、それらはまったく同じになるはずです。

たとえば、こちらの署名文字列のサンプルを使用すると、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>
于 2012-11-14T17:54:29.193 に答える
1

C# は結果を符号なしバイトとして扱いますが、ColdFusion はそれらを符号付きバイトとして扱います。

128 未満の値は C# と ColdFusion の両方で同じですが、C# で 128 を超える値は ColdFusion では負 ( 2 の補数) です。

したがって、逆に変換するには、負の値に 256 を加算します。

編集

これは、BinaryDecode から返される実際のバイトでは問題にならない場合があります。デバッグ中に ColdFusion がこれらのバイトを画面に出力する方法に問題がある可能性があります。

C# と ColdFusion から取得した実際のバイナリ値を比較します (たとえば、値を画面に出力するのではなく、バイナリ ファイルに保存します)。

于 2012-11-14T03:29:36.520 に答える