5

で次のコードを複製しようとしていますPHP。これは、インターフェイスする必要がある API のサンプル コードです (API とサンプル コードは にあります。C#私のアプリは にありPHP 5.3ます)。私は C# 開発者ではないので、これを行うのに問題があります。

// C# Code I am trying to replicate in PHP
var apiTokenId = 1887;
var apiToken = "E1024763-1234-5678-91E0-T32E4E7EB316";

// Used to authenticate our request by the API (which is in C#)
var stringToSign = string.Empty;
stringToSign += "POST"+"UserAgent"+"http://api.com/post";

// Here is the issue, How can I do the following 3 lines in PHP?
// No "secret key" provided?.. How do I do this in PHP?
var hmacsha1 = new HMACSHA1(new Guid(apiToken).toByteArray());

// Make a byte array with ASCII encoding.
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(stringToSign);

// Finally, 'computeHash' of the above (what does this do exactly?!)
var calculatedSignature = Convert.ToBase64String(hmacsha1.ComputeHash(byteArray));

オンラインで見つけた他の機能を使用して多くのバリエーションを試しpack()ましたが、比較するものがないため、正しく実行したかどうかわかりません。

C# 開発者は上記のコードを実行し、生成された値を投稿して、それを使用してチェック/テストできますか?

MSDNをチェックして、これらのメソッドが何をするかを確認しようとしましたが、スタックしています (比較するものが何もないため、正しいかどうかはわかりません)。

PHP 疑似コード

// Set vars
$apiToken = 'E1024763-1234-5678-91E0-T32E4E7EB316';
$apiTokenId = '1887';
$stringToSign = "POST"."UserAgent"."http://api.com/post";

// HowTo: Build a `byteArray` of our apiToken? (i think)
// C#: var hmacsha1 = new HMACSHA1(new Guid(apiToken).toByteArray());

// HowTo: Convert our $stringToSign to a ASCII encoded `byteArray`?
// C#: byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(stringToSign);

// HowTo: Generate a base64 string of our (`hmacsha1`.ComputeHash(byteArray))
// C#: var calculatedSignature = Convert.ToBase64String(hmacsha1.ComputeHash(byteArray));

これは非常に単純でわかりやすいように聞こえますが、これらの C# メソッドのいくつかが何をするのかわかりません..

C#これらのメソッドは何をする/返すのですか?

  • ComputeHash(byteArray)- 何に計算されますか?.何が返されますか?
  • System.Text.Encoding.ASCII.GetBytes(stringToSign);- これは何を返しますか?
  • new HMACSHA1(new Guid(apiToken).toByteArray());秘密鍵がありませんか?、使用される鍵は何ですか?

リソースやヘルプをいただければ幸いです。SOで他の回答のバリエーションを試しましたが、喜びはありませんでした。

JSFiddle各行の出力を確認できるように、3 行のコードをオンラインのどこかで実行することはC#できますか?


更新 - バウンティが追加されました

これにはまだ問題がありC#ますが、Visual Studio でコードをテストすることはできましたが、.NET で生成された同じハッシュを取得するのに問題がありPHPます。

をお願いします...

.. 上記のC#コード (具体的には、SHA1ハッシュを作成する 3 行) を PHP に変換します (Pseudo Code上記の投稿を確認してください)。C#PHPを使用してハッシュを一致させることができるはずです。

その他ご不明な点がございましたら、お尋ねください。

4

3 に答える 3

3

問題は、GUID の文字列形式が、GUID の最初の 3 つのセグメントで 2 文字の 16 進数の順序を逆にすることです。詳細については、次の例のコメントを参照してください: http://msdn.microsoft.com/en-us/library/system.guid.tobytearray.aspx

次のコードが機能するはずです。

$apiTokenId = 1887;
$apiToken = "E1024763-1234-5678-91E0-FF2E4E7EB316";
$stringToSign = '';
$hexStr = str_replace('-','',$apiToken);
$c = explode('-',chunk_split($hexStr,2,'-'));
$hexArr = array($c[3],$c[2],$c[1],$c[0],$c[5],$c[4],$c[7],$c[6],$c[8],$c[9],$c[10],$c[11],$c[12],$c[13],$c[14],$c[15]);
$keyStr = '';
for ($i = 0; $i < 16; ++$i) {
    $num = hexdec($hexArr[$i]);
    $keyStr .= chr($num);
}
$stringToSign .= "POST" . "UserAgent" . "http://api.com/post";
$hmacsha1 = base64_encode(hash_hmac('sha1',$stringToSign,$keyStr,true));

上記で提供された C# コードに対してこのコードをテストしましたが、出力は同じでした。ただし、元のコードで指定された GUID は有効ではないため、少し変更する必要がありました。

于 2013-06-25T20:38:25.943 に答える
0

コードをテストする必要がない場合、それは非常に簡単です:P

http://php.net/manual/en/function.hash-hmac.php - HMACSHA1 c# クラスに相当します。

文字列 hash_hmac (文字列 $algo 、文字列 $data 、文字列 $key [, bool $raw_output = false ] )

したがって、$algo = "sha1"

$data はあなたの $stringToSign です - それはすでにアスキー文字列であるため (私は願っています) - C# は同じバイトに相当するものを取っているだけです。

new Guid(apiToken).toByteArray() -> GUID の 16 バイト (16*8 = 128) 表現 - 32*4 = 128 ビット。これが鍵です。

$key は文字列であるため、$apiToken に相当する ASCII 文字列が必要です (これは 32 個の 16 進文字です - 最初のストリップ / 間のダッシュを無視します) - E10247631234567891E0T32E4E7EB316 (キーを修正します - 「T」を含めることはできません)

function hex2str($hex) {
    for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
    return $str;
}

$hexKey = hex2str($apiToken); //strip the dashes first

http://www.linux-support.com/cms/php-convert-hex-strings-to-ascii-strings/

したがって、メソッド呼び出しが機能するようになりました:

$almostResult = hash_hmac ("sha1" , $stringToSign, $hexKey, true)

これは、base64 エンコーディングに変換する必要があるバイナリ文字列を返します。

$final = base64_encode ($almostResult)

それはそれを行う必要があります...お楽しみください:)

于 2013-06-25T19:48:06.730 に答える