2009-11-14 46 views
8

我想從ankoder.com測試API,並且在authentication token的摘要計算上有問題。當我嘗試從C#調用時,示例是紅寶石。當我比較HMAC-SHA1之間的摘要結果時,我遇到了密鑰結果的問題。紅寶石hmac-sha1不同於C#HMACSHA1

爲了方便在這裏測試的是代碼:

require 'hmac-sha1' 
require 'digest/sha1' 
require 'base64' 
token="-Sat, 14 Nov 2009 09:47:53 GMT-GET-/video.xml-" 
private_key="whatever" 
salt=Digest::SHA1.hexdigest(token)[0..19] 
passkey=Base64.encode64(HMAC::SHA1.digest(private_key, salt)).strip 

這使我的結果是: 「X/0EngsTYf7L8e7LvoihTMLetlM = \ n」 個 如果我嘗試在C#與以下:

const string PrivateKey = "whatever"; 

var date = "Sat, 14 Nov 2009 09:47:53 GMT";//DateTime.Now.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT"; 
string token=string.Format("-{0}-GET-/video.xml-", date); 

var salt_binary=SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(token)); 
var salt_hex=BitConverter.ToString(salt_binary).Replace("-", "").ToLower(); 
var salt =salt_hex.Substring(0,20); 

var hmac_sha1 = 
      new HMACSHA1(Encoding.ASCII.GetBytes(salt)); 
hmac_sha1.Initialize(); 

var private_key_binary = Encoding.ASCII.GetBytes(PrivateKey); 
var passkey_binary = hmac_sha1.ComputeHash(private_key_binary,0,private_key_binary.Length); 

var passkey = Convert.ToBase64String(passkey_binary).Trim(); 

鹽結果是相同的,但密鑰的結果不同 - C#給我:

QLC68XjQlEBurwbVwr7euUfHW/K =

兩者都產生鹽:f5cab5092f9271d43d2e

任何好主意發生了什麼?

回答

10

您已將PrivateKeysalt放在C#代碼的錯誤位置上;根據你的Ruby代碼,PrivateKey被認爲是HMAC的祕密密鑰。

另請注意,您的Ruby程序生成的哈希末尾包含換行符(根據您的示例輸出,無論如何)。您必須而不是包含換行符或哈希將不匹配。

這個C#程序糾正了第一個問題:

using System; 
using System.Security.Cryptography; 
using System.Text; 

namespace Hasher 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     const string PrivateKey = "whatever"; 

     string date = "Sat, 14 Nov 2009 09:47:53 GMT"; 
     string token = string.Format("-{0}-GET-/video.xml-", date); 

     byte[] salt_binary = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(token)); 
     string salt_hex = BitConverter.ToString(salt_binary).Replace("-", "").ToLower(); 
     string salt = salt_hex.Substring(0, 20); 

     HMACSHA1 hmac_sha1 = new HMACSHA1(Encoding.ASCII.GetBytes(PrivateKey)); 
     hmac_sha1.Initialize(); 

     byte[] private_key_binary = Encoding.ASCII.GetBytes(salt); 
     byte[] passkey_binary = hmac_sha1.ComputeHash(private_key_binary, 0, private_key_binary.Length); 

     string passkey = Convert.ToBase64String(passkey_binary).Trim(); 
    } 
    } 
} 
+0

只是想知道,你會得到什麼結果呢? – quantumpotato

+0

X/0EngsTYf7L8e7LvoihTMLetlM = –

3

我看到2個問題,

  1. 你得到扭轉鍵/數據。在Ruby中,private_key是關鍵,salt是數據。在C#中,你做了相反的事情。
  2. 如果任何字符串都允許使用非ASCII字符,則必須確保使用相同的編碼。 Ruby將所有內容視爲原始字節,因此C#必須與其編碼匹配。如果使用jcode,則C#中的編碼應該匹配$ KCODE。