2013-12-13 5 views
10

Facebook erfordert zu erstellen, dass ich eine appsecret_proof erstellen: https://developers.facebook.com/docs/graph-api/securing-requests# help C erforderlich Face AppSecret_Proof HMACSHA256

Und ich habe dies mit dem folgenden Code getan:

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

Alles sieht gut für mich, aber Facebook sagt dass der appsecret_proof ungültig ist. Ich bin eingeloggt, ich kann alles normal machen, wenn ich den Schlüssel entferne. So etwas Zeit zu sparen:

  • Ja ich auf die richtige URL bin Entsendung
  • Ja ich vorbei ein gültiges access_token
  • Ja ich das gleiche access_token im Beweis verwenden, wie ich in der Anfrage am
  • Ja mein appsecret ist in Ordnung, und arbeitet

Beispiel in Verwendung

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

Ich denke, es hat wahrscheinlich etwas mit Kodierung oder etwas in dieser Richtung zu tun, aber um ehrlich zu sein, ich weiß es einfach nicht.

ich auch die Facebook .net SDK jedoch bin mit dieser nicht viel in der Dokumentation hat, und scheint nicht auf irgendetwas zu schlagen mit Automatisierung, Server-Seite Operationen usw.

Dank

+0

können Sie mehr Code zeigen, bitte - wie schafft man 'Klient'? Sind Sie sicher, dass Sie dieselbe App.Id für Hash und Anfrage verwenden? Auch - versuchen Sie 'Encoding.UTF8.GetBytes' nur für den Fall - vielleicht wird das den Trick ... – avs099

+0

Ich hatte das gleiche Problem und löste es für Facebook APIs v2.4 hier: http://stackoverflow.com/fragen/31932675/how-to-send-appsecret-proof-using-facebook-c-sharp-sdk/31933544 # 31933544 – Yovav

Antwort

1

Das zu tun app secret ist eine Base-16-Zeichenfolge, also müssen Sie diese in ein Byte-Array konvertieren. Details hierzu finden Sie unter How can I convert a hex string to a byte array?. Das access_token muss mithilfe der ASCII-Codierung in ein Byte-Array konvertiert werden. Sobald Sie den HMAC generiert haben, kodieren Sie ihn als Basis-16-String, um ihn als appsecret_proof zu verwenden. Der folgende Code konvertiert ein Byte-Array in 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); 
    } 

Der Code der appsecret_proof dann

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 entweder zu akzeptieren scheint eine SHA256 HMAC oder SHA1 HMAC wäre zu erzeugen.

+0

nice one, danke – davethecoder

+0

Diese Antwort fehlt die Base16.Decode-Implementierung. Sollen wir das für uns selbst herausfinden? Es erstaunt mich, dass dies die akzeptierte Antwort statt der von Eric Kassan gegebenen ist, die komplett ist, korrekt und es funktioniert ohne viel Hektik. – MoSs

+0

Ich habe den Code für Base16.Decode nicht enthalten, da es viele Lösungen zu diesem bereits in der Frage gibt, die ich verknüpfte (und das zugehörige Duplikat). http: // Stapelüberlauf.com/questions/321370/convert-hex-string-zu-byte-array http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and -Vice-Versa Eric Kassan Lösung ist interessant für sich selbst, weil er nur UTF8.GetBytes verwendet, um die AppSecret zu dekodieren. Dies würde bedeuten, dass Facebook den appsecret_proof mit mehreren Variationen des Algorithmus validiert. – Steve

13

ich verwendet habe, die unten erfolgreich mit 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(); 
}