2013-12-13 49 views
10

Facebook đòi hỏi mà tôi tạo ra một appsecret_proof: https://developers.facebook.com/docs/graph-api/securing-requestsC# giúp đỡ cần thiết để tạo Facebook AppSecret_Proof HMACSHA256

Và tôi đã làm điều này bằng cách sử dụng đoạn mã sau:

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

Tất cả mọi thứ có vẻ tốt đẹp đối với tôi, tuy nhiên facebook nói rằng appsecret_proof không hợp lệ. Tôi đã đăng nhập, tôi có thể làm mọi thứ như bình thường khi tôi xóa khóa. Vì vậy, để tiết kiệm thời gian:

  • Có Tôi gửi bài đến URL chính xác
  • Có, tôi đang đi qua một hợp lệ access_token
  • Có, tôi đang sử dụng access_token cùng trong chứng minh, như tôi trong yêu cầu
  • có appsecret của tôi là tốt, và các công trình

Ví dụ trong việc sử dụng

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

Tôi nghĩ rằng nó có thể có một cái gì đó để làm với mã hóa hoặc một cái gì đó dọc theo họ dòng, nhưng phải trung thực, tôi chỉ không biết.

Tôi cũng đang sử dụng .net SDK Facebook tuy nhiên điều này không có nhiều trong tài liệu, và dường như không để tấn công vào bất cứ điều gì để làm với tự động hóa, các hoạt động phía máy chủ, vv

Cảm ơn

+0

bạn có thể hiển thị mã chi tiết xin - làm thế nào để bạn tạo 'client'? Bạn có chắc là bạn đang sử dụng cùng một app.Id cho cả băm và yêu cầu? Ngoài ra - hãy thử 'Encoding.UTF8.GetBytes' chỉ trong trường hợp - có thể là sẽ làm các trick ... – avs099

+0

Tôi đã có cùng một vấn đề và giải quyết nó cho API facebook v2.4 ở đây: http://stackoverflow.com/questions/31932675/how-to-send-appsecret-proof-using-facebook-c-sharp-sdk/31933544 # 31933544 – Yovav

Trả lời

1

Các bí mật ứng dụng là chuỗi cơ sở-16, vì vậy bạn cần chuyển đổi chuỗi đó thành mảng byte. Hãy xem How can I convert a hex string to a byte array? để biết chi tiết về cách thực hiện việc này. Access_token cần được chuyển đổi thành mảng byte sử dụng mã hóa ASCII. Một khi bạn đã tạo ra HMAC sau đó mã hóa nó như là một chuỗi base-16 để sử dụng như appsecret_proof của bạn. Đoạn mã sau sẽ chuyển đổi một mảng byte thành 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); 
    } 

Mã để tạo ra appsecret_proof sau đó sẽ là

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 dường như chấp nhận hoặc là một SHA256 HMAC hoặc SHA1 HMAC.

+0

đẹp, cảm ơn – davethecoder

+0

Câu trả lời này thiếu cơ sở triển khai Base16.Decode. Chúng ta có nên hình dung điều này cho bản thân mình không? Tôi ngạc nhiên rằng câu trả lời này là câu trả lời được chấp nhận thay vì câu trả lời được đưa ra bởi Eric Kassan hoàn chỉnh, chính xác và nó hoạt động mà không có nhiều sự huyên náo. – MoSs

+0

Tôi không bao gồm mã cho Base16.Decode vì có nhiều giải pháp cho điều này đã có trong câu hỏi tôi đã liên kết tới (và bản sao liên quan). http: // stackoverflow.com/questions/321370/chuyển đổi-hex-string-to-byte-mảng http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and -vice-versa Giải pháp Eric Kassan rất thú vị vì nó chỉ sử dụng UTF8.GetBytes để giải mã appSecret. Điều này có nghĩa là Facebook xác thực ứng dụng appsecret_proof với nhiều biến thể của thuật toán. – Steve

13

Tôi đã sử dụng dưới đây thành công với 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(); 
} 
Các vấn đề liên quan