Я работаю с Facebook и анализирует подписанный запрос в сервлете Java с использованием декодера Sun Base64. Я получаю сбои подписи, хотя подпись выглядит почти. Я не могу понять, почему это не соответствует точно, и я считаю, что это проблема с моим кодом. Минимальный код, чтобы увидеть, что я делаю:Facebook подписанный запрос декодирования hash не соответствует точно
BASE64Decoder decoder = new BASE64Decoder();
String[] parts = request.getParameter("signed_request").split("\\.", 2);
String signature = new String(decoder.decodeBuffer(parts[0]), "UTF-8");
String rawData = new String(decoder.decodeBuffer(parts[1]), "UTF-8");
if (!isSignedRequestValid(request, obj, signature, parts[1]))
...
private boolean isSignedRequestValid(HttpServletRequest request, JSONObject obj, String signature, String data) throws IOException
{
String expectedSignature = generateSha256Signature(data, FacebookAppSecretKey);
if (!signature.equals(expectedSignature))
{
log("Facebook signatures do not match, expected: " + expectedSignature + ", received: " + signature);
return false;
}
}
private String generateSha256Signature(String data, String key) throws Exception
{
java.net.URLDecoder decoder = new java.net.URLDecoder();
data = decoder.decode(data, "UTF-8"); // mostly here for testing, doesn't seem to make a difference
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(hmacData);
}
Я бегу в две проблемы ... во-первых, ожидаемые против представленные подписи 32 против 33 байта. Но если я сравниваю только первые 32 байта, иногда они равны, но когда он не соответствует, он не соответствует точно одному биту. Например, распечатав индексы и значения один из примеров:
index 14 : [15] , [15]
index 15 : [71] , [71]
index 16 : [-10] , [-26] <-- note the different here, which is 16, or one bit
index 17 : [28] , [28]
index 18 : [60] , [60]
Я новичок в разборе Facebook запросы, так что я должен верить, что есть что-то я пропустил в коде, но я не вижу его, и играли с ним достаточно долго, чтобы нуждаться в помощи. И я не вижу ответа нигде в Интернете. Спасибо!
Вы не можете анализировать суровые байты (такие как SHA-хеши) как UTF8. – SLaks
Я не думаю, что это было так. Я изменил все байтовые массивы, просто используя decoder.decodeBuffer(), возвращает массив байтов и сравнивает это с hmacData, который является байтовым массивом. Оказывается, они имеют разную длину, 32 против 33. Тот, который я генерирую из метода сгенерированной подписи, составляет 32 байта. Тот, который я получаю из facebook в подписанном запросе, составляет 33 байта. Это заставляет меня задаться вопросом, имеет ли функция декодера ошибка. Кроме того, он зависит от данных. Если я запускаю его несколько раз, иногда он сравнивается правильно (сравнивая первые 32 байта), иногда нет. Так что что-то в данных, кажется, имеет значение. – user1676075
Интересно, связано ли это с преобразованием пространства в +? – user1676075