2013-12-13 35 views
10

Facebook wymaga, aby utworzyć appsecret_proof: https://developers.facebook.com/docs/graph-api/securing-requestsC# help wymagane do utworzenia Facebook AppSecret_Proof HMACSHA256

i zrobiłem to za pomocą następującego kodu:

public string FaceBookSecret(string content, string key) 
{ 
     var encoding = new System.Text.ASCIIEncoding(); 
     byte[] keyByte = encoding.GetBytes(key); 
     byte[] messageBytes = encoding.GetBytes(content); 
     using (var hmacsha256 = new HMACSHA256(keyByte)) 
     { 
      byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); 
      return Convert.ToBase64String(hashmessage); 
     } 
} 

wszystko wygląda w porządku dla mnie, jednak mówi facebook że appsecret_proof jest nieprawidłowy. Jestem zalogowany, mogę zrobić wszystko normalnie po usunięciu klucza. Tak aby zaoszczędzić trochę czasu:

  • Tak jestem delegowania do prawidłowego adresu URL
  • Tak ja przechodząc ważny access_token
  • Tak używam tego samego access_token w dowodzie, jak jestem w żądaniu
  • Tak mój appsecret jest w porządku i działa

przykład w wykorzystaniu

dynamic results = client.Post("/" + model.PostAsId + "/feed", new { message = model.Message, appsecret_proof = FaceBookSecret(postAs.AuthToken, AppSecret) }); 

Myślę, że prawdopodobnie ma to coś wspólnego z kodowaniem lub czymś w rodzaju linii, ale szczerze mówiąc, po prostu nie wiem.

Jestem również za pomocą Facebook .net SDK to jednak nie ma wiele w dokumentacji, a nie wydaje się, aby uderzyć na cokolwiek zrobić z automatyki, operacje po stronie serwera itp

Dzięki

+0

można pokazać więcej kodu proszę - w jaki sposób tworzyć 'client'? Czy na pewno używasz tego samego app.Id zarówno dla hash i wniosek? Również - spróbuj "Encoding.UTF8.GetBytes" na wszelki wypadek - może to wystarczy ... – avs099

+0

Miałem ten sam problem i rozwiązałem go dla facebook APIs v2.4 tutaj: http://stackoverflow.com/questions/31932675/how-to-send-appsecret-proof-using-facebook-c-sharp-sdk/31933544 # 31933544 – Yovav

Odpowiedz

1

Sekretem aplikacji jest ciąg znaków base-16, więc musisz go przekonwertować na tablicę bajtów. Spójrz na How can I convert a hex string to a byte array?, aby uzyskać szczegółowe informacje, jak to zrobić. Element access_token musi zostać przekonwertowany na tablicę bajtów za pomocą kodowania ASCII. Kiedy już wygenerujesz HMAC, zakoduj to jako ciąg 16-sza do użycia jako appsecret_proof. Poniższy kod przekonwertuje tablicę bajtową na base16.

public static class Base16 
{ 
    private static readonly char[] encoding; 

    static Base16() 
    { 
     encoding = new char[16] 
     { 
      '0', '1', '2', '3', '4', '5', '6', '7', 
      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 
     }; 
    } 

    public static string Encode(byte[] data) 
    { 
     char[] text = new char[data.Length * 2]; 

     for (int i = 0, j = 0; i < data.Length; i++) 
     { 
      text[j++] = encoding[data[i] >> 4]; 
      text[j++] = encoding[data[i] & 0xf]; 
     } 

     return new string(text); 
    } 

Kod do generowania appsecret_proof będzie wówczas

private string GenerateAppSecretProof(string accessToken, string appSecret) 
{ 
    byte[] key = Base16.Decode(appSecret); 
    byte[] hash; 
    using (HMAC hmacAlg = new HMACSHA1(key)) 
    { 
     hash = hmacAlg.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); 
    } 
    return Base16.Encode(hash); 
} 

Facebook wydaje się akceptować albo SHA256 HMAC lub SHA1 HMAC.

+0

nice one, thanks – davethecoder

+0

Ta odpowiedź nie zawiera implementacji Base16.Decode. Czy powinniśmy to rozgryźć dla samych siebie? Zdumiewa mnie, że ten jest akceptowaną odpowiedzią, a nie tą, którą podał Eric Kassan, która jest kompletna, poprawna i działa bez wielu kłopotów. – MoSs

+0

Nie uwzględniłem kodu dla Base16.Decode, ponieważ istnieje wiele rozwiązań tego już w pytaniu, z którym się łączyłem (i powiązanym duplikatem). http: // stackoverflow.com/questions/321370/convert-hex-string-to-byte-array http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and -wers-versa Rozwiązanie Eric Kassan jest interesujące samo w sobie, ponieważ właśnie użył UTF8.GetBytes do odkodowania appSecret. Sugerowałoby to, że Facebook zatwierdza appsecret_proof z wieloma odmianami algorytmu. – Steve

13

Użyłem poniżej powodzeniem z Facebook

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

internal static string FaceBookSecret(string content, string key) 
{ 
    byte[] keyBytes = Encoding.UTF8.GetBytes(key); 
    byte[] messageBytes = Encoding.UTF8.GetBytes(content); 
    byte[] hash; 
    using (HMACSHA256 hmacsha256 = new HMACSHA256(keyBytes)) 
    { 
     hash = hmacsha256.ComputeHash(messageBytes); 
    } 

    StringBuilder sbHash = new StringBuilder(); 
    for (int i = 0; i < hash.Length; i++) 
    { 
     sbHash.Append(hash[i].ToString("x2")); 
    } 
    return sbHash.ToString(); 
}