2009-11-14 9 views
8

Próbuję przetestować API od ankoder.com i mam problem w obliczeniach trawienia dla authentication token. Próbka jest ruby, gdy próbuję wywołać z C#. Kiedy porównuję wynik trawienia między HMAC-SHA1, mam problemy z wynikiem hasła.hmac-sha1 w ruby ​​różni się od C# HMACSHA1

Aby ułatwić testowanie oto kod:

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 

Który daje mi wynik: "X/0EngsTYf7L8e7LvoihTMLetlM = \ n" Gdy próbuję to w C# z poniższym:

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(); 

wynik sól jest taka sama, ale Klucz wynik różnych-C# daje mi:

QLC68XjQlEBurwbVwr7euUfHW/k =

Obie generują sól: f5cab5092f9271d43d2e

Czy wiesz, co się stało?

Odpowiedz

10

Położyłeś PrivateKey i salt na niewłaściwych pozycjach w twoim kodzie C#; Twój kod Ruby, PrivateKey, ma być tajnym kluczem HMAC.

Należy również pamiętać o dodaniu znaku nowej linii na końcu skrótu wygenerowanego przez program Ruby (w każdym razie). Musisz nie dołączyć nowego wiersza lub skróty nie będą pasować.

Ten program w C# koryguje pierwszy problem:

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

Zastanawiasz się, jaki masz wynik? – quantumpotato

+0

X/0EngsTYf7L8e7LvoihTMLetlM = –

3

widzę 2 problemy,

  1. Ty dostał klucz/dane odwrócone. W Ruby klucz prywatny to klucz prywatny, a sól to dane. W języku C# zrobiliście coś odwrotnego.
  2. Jeśli w żadnym z twoich ciągów dozwolona jest wartość inna niż ASCII, musisz upewnić się, że używasz tego samego kodowania. Ruby traktuje wszystko jako surowe bajty, więc C# musi dopasować kodowanie. Jeśli użyto jcode, kodowanie w C# powinno pasować do $ KCODE.
Powiązane problemy