2016-08-12 51 views
5

Mam następujący kod w C#Computing Podpis/Hash w JavaScript i mieć taki sam wynik jak C#

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ=="; 
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ="; 

var key = Convert.FromBase64String(apiSecret); 
var provider = new System.Security.Cryptography.HMACSHA256(key); 

var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(apiKey)); 
var signature = Convert.ToBase64String(hash); 

Próbuję uzyskać ten sam rezultat w JavaScript z wykorzystaniem biblioteki CryptJS ale z tego co mogę powiedzieć I nie konwertuję klucza i sekretu na tablice bajtów, a kodowanie jest niepoprawne. Pierwsza próba wygląda następująco:

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ=="; 
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ="; 
var hash = CryptoJS.HmacSHA256(apiKey, apiSecret); 
var sig = hash.toString(CryptoJS.enc.Base64); 
+2

Czytaj kodu, które zostały zamieszczone tutaj ponownie. Zapomniałeś przetworzyć kodowane przez Base64 'apiSecret' w CryptoJS. Co gorsza, zapomniałeś całkowicie przekazać 'apiKey' i' apiSecret' do 'CryptoJS.HmacSHA256'. –

+0

To było szybkie wycięcie i wklejenie oryginalnego kodu z dokumentów CryptoJS. Przekazywanie poprawnych wartości nadal go nie naprawia, ale dzięki za wskazanie tego. Czy masz jakiś rzeczywisty wgląd w to, żeby to działało? –

+1

Tak, mam rzeczywisty wgląd, który już wam udostępniłem. Już powinieneś mieć narzędzia, które sprawią, że będzie działać. Czy masz problemy z analizowaniem łańcucha zakodowanego w Base64 za pomocą CryptoJS? Jeśli nie, czy zamieniłeś kolejność argumentów na 'CryptoJS.HmacSHA256'? –

Odpowiedz

8

Inspire przez https://stackoverflow.com/a/13837543/1810391

JavaScript

var CryptoJS = require('crypto-js'); 

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ=="; 
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ="; 

// var key = Convert.FromBase64String(apiSecret); 
var key = CryptoJS.enc.Base64.parse(apiSecret); 
console.log('key:' + key); 

// var prehash = Encoding.UTF8.GetBytes(apiKey); 
var prehash = CryptoJS.enc.Utf8.parse(apiKey); 
console.log('Pre-hash:' + prehash); 

// var provider = new System.Security.Cryptography.HMACSHA256(key); 
// var hash = provider.ComputeHash(prehash); 
var hash = CryptoJS.HmacSHA256(prehash, key); 
console.log('hash:' + hash); 

//var signature = Convert.ToBase64String(hash); 
var signature = hash.toString(CryptoJS.enc.Base64); 
console.log('signature:' + signature); 

JavaScript Output

key:41a4d6df195fd54e658dd940252765b734fbd5f145f9e6 
Pre-hash:53424233615778734947316861325567625862635156424a49484e7c593356795a513d3d 
hash:ecb6cdf5dd39872bb2cbce4321e2725e11b99c01af9c2a620ebbaf3d8d8607e7 
signature:7LbN9d05hyuyy85DIeJyXhG5nAGvnCpiDruvPY2GB+c= 

C#

using System; 
using System.Text; 

namespace ConsoleApplication 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ=="; 
      var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ="; 
      var key = Convert.FromBase64String(apiSecret); 
      Console.Write("key:"); 
      prtByte(key); 

      Console.Write("Pre-hash:"); 
      prtByte(Encoding.UTF8.GetBytes(apiKey)); 
      var provider = new System.Security.Cryptography.HMACSHA256(key); 
      var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(apiKey)); 
      Console.Write("hash:"); 
      prtByte(hash); 

      var signature = Convert.ToBase64String(hash); 
      Console.WriteLine("signature:" + signature); 
     } 
     public static void prtByte(byte[] b) 
     { 
      for (var i = 0; i < b.Length; i++) 
      { 
       Console.Write(b[i].ToString("x2")); 
      } 
      Console.WriteLine(); 
     } 
    } 
} 

C# Wyjście

key:41a4d6df195fd54e658dd940252765b734fbd5f145f9e6 
Pre-hash:53424233615778734947316861325567625862635156424a49484e7c593356795a513d3d 
hash:ecb6cdf5dd39872bb2cbce4321e2725e11b99c01af9c2a620ebbaf3d8d8607e7 
signature:7LbN9d05hyuyy85DIeJyXhG5nAGvnCpiDruvPY2GB+c= 
+0

Cześć John, bardzo dziękuję za poświęcenie czasu. Bardzo to doceniam. Problem tutaj jest mój oryginalny C# jest poprawny i potrzebuję JS, aby obliczyć ten sam podpis co podany C#. Sygnatura wygląda jak UufyTxE87/MsjPkLVBBm39G5H1O4bnMj17qSXqyO2/0 =. Może jesteś blisko? Jeszcze raz dziękuję za poświęcenie czasu. Nie wiem, dlaczego ludzie go ignorują. –

+1

@billyjean Moje C# jest w rzeczywistości twoim kodem, jedynymi zmianami są wszystkie 'Console.Write'. Testowałem na oknach 10 i os x box i zarówno C# jak i js dają ten sam rezultat. Czy używasz tego samego "apiKey" i "apiSecret", które zamieściłeś w pytaniu? –

+0

John miałeś absolutną rację. Przepraszam za zamieszanie. Właśnie przejrzałem twój kod, zaimplementowałem go do mojego rozwiązania i ponowiłem próbę i wszystko działa. Dzięki wielkie. Szkoda, że ​​nie miałem więcej do wysłania niż przedstawiciel. Ponownie nie jestem pewien, dlaczego jest to odrzucone. Jest to jedyne kompletne rozwiązanie tego problemu. Jest to problem dla wszystkich osób próbujących połączyć się z interfejsem API .Net z JS, który wymaga użycia tego schematu zabezpieczeń. –