2012-06-03 3 views
1

Итак, я работаю над проверкой подписки на Facebook с помощью Java. К сожалению, я все время сталкиваюсь с проблемами с процессом проверки. Я посмотрел на this documentation и эмулировал их алгоритм, без успеха. Я также следовал this tutorial и продолжал придумывать, что моя рассчитанная подпись отличается от той, которую отправил Facebook.HMAC SHA-256 и Facebook signed_request

По крайней мере, это то, о чем мне рассказывал String.equals().

Так что я решил еще раз подсунуть ему.

Я установил его для повторения по байтам в моей рассчитанной сигнатуре и предоставленных. Низкий и вот, первые 32 байта моей подписи соответствовали их точно. Он просто пропускал еще 400 байтов данных.

В этот момент я решил, что, вероятно, должен получить лучшее представление о том, что происходит. Я посмотрел на SHA-256 и нашел, что действительно, it only creates 32 bytes of information. Итак, у меня осталось более 400 байт данных, которые, по мнению Facebook, были сгенерированы с использованием алгоритма HMAC SHA-256. Я думал, что мне нужно сравнить максимальную длину SHA-256 с длиной данных, которые я хеширую, но это только что показало, что есть способ, путь, путь к большому количеству места (размер сообщения: 575 байт, максимальный размер : 2.305843009213694 x 10^18 байт).

Является ли Facebook создание дерьма? Или я чего-то не хватает?

редактировать

Это функция я использую хэш данных. Я передаю свой секретный код facebook (для ключа) и объект JSON, закодированный base64url (для данных). Он последовательно возвращает массив байтов длиной 32 с данными, которые соответствуют первым 32 байтам подписи, предоставленной facebook.

private byte[] hmacSHA256(String data, String key) throws Exception { 
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); 
    Mac mac = Mac.getInstance("HmacSHA256"); 
    mac.init(secretKey); 
    mac.update(data.getBytes("UTF-8")); 
    byte[] hmacData = mac.doFinal(); 
    return hmacData; 
} 

ответ

6

Так как я также пришел сюда, чтобы найти ответ на аналогичную проблему. Это код, который подходит для меня:

import org.apache.commons.codec.binary.Base64; 
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 

private JSONObject parseFBSignedRequest(String signedRequest, String secret) throws UnsupportedEncodingException, Exception { 
    //split request into signature and data 
    String[] signedRequests = signedRequest.split("\\.", 2); 
    //parse signature 
    String sig = signedRequests[0]; 

    //parse data and convert to json object 
    String data = signedRequests[1]; 

    //I assumed it is UTF8 
    JSONObject jsonData = new JSONObject(new String(Base64.decodeBase64(data), "UTF-8")); 
    //check signature algorithm 
    if(!jsonData.getString("algorithm").equals("HMAC-SHA256")) { 
     //unknown algorithm is used 
     return null; 
    } 

    //check if data is signed correctly 
    if(!hmacSHA256(signedRequests[1], secret).equals(sig)) { 
     //signature is not correct, possibly the data was tampered with 
     return null; 
    } 
    return jsonData; 
} 

//HmacSHA256 implementation 
private String hmacSHA256(String data, String key) throws Exception { 
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); 
    Mac mac = Mac.getInstance("HmacSHA256"); 
    mac.init(secretKey); 
    byte[] hmacData = mac.doFinal(data.getBytes("UTF-8")); 
    return new String(Base64.encodeBase64URLSafe(hmacData), "UTF-8"); 
} 
+0

Спасибо!Мне действительно удалось выяснить, что не так с моей (я идиот, и не назначал значение строки, в которой выполнял операцию). Я дам вам ответ, поскольку вы предоставили код. – Chaosphere2112

+0

Спасибо, сэр. Функция hmacSHA256 не вернула мне правильное значение, затем я объединил ваш ответ с [другим, найденным в SO] (https://stackoverflow.com/questions/3103652/hash-string-via-sha-256-in -java) и придумал этот оператор return: 'return String.format («% 064x », новый java.math.BigInteger (1, hmacData));' – Seza

0

Я посмотрел SHA-256, и обнаружил, что, на самом деле, это только создает 32 байт информации. Итак, у меня осталось более 400 байт данных, которые, по мнению Facebook, были сгенерированы с использованием алгоритма HMAC SHA-256.

Данные подписанного запроса не «создан» использованием HMAC SHA-256 - это подписал с ним.

Первая часть подписанного запроса, перед точкой, является подписи - остальное данные полезной нагрузки. Вы должны хэшировать данные полезной нагрузки и сравнивать хэш с вашей подписью - эти два должны совпадать, чтобы доказать, что подписанный запрос является подлинным.

Если это не поможет вам разобраться в этом, пожалуйста, сообщите нам код.

+0

Добавлен код, посмотрите на это. Я понимаю, что полезная нагрузка и подпись различны. Подпись, как предполагается, является полезной нагрузкой, хэшированной с использованием секретного приложения в качестве ключа. Есть ли другой подход, который я должен использовать для хэш-данных, чем то, что я использую выше? – Chaosphere2112

Смежные вопросы