java - HMAC SHA-256 和 Facebook signed_request

标签 java facebook sha256

因此,我正在使用 Java 验证 Facebook 的 signed_request。不幸的是,我一直在验证过程中遇到问题。我看过 this documentation ,并模仿他们的算法,但没有成功。我也关注了this tutorial ,并继续提出我计算出的签名与 Facebook 发送的签名不同。

或者至少,这是 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 密码(用于 key )和 base64url 编码的 JSON 对象(用于数据)。它始终返回一个长度为 32 的字节数组,其中的数据与 facebook 提供的签名的前 32 个字节相匹配。

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

最佳答案

因为我也是来这里寻找类似问题的答案的。 这是对我有用的代码:

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

关于java - HMAC SHA-256 和 Facebook signed_request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10874081/

相关文章:

php - Facebook 应用程序,好友数据访问 token 不起作用

javascript - Facebook Javascript SDK Audience Network 错误 1003

c - C 函数的哈希值

java - AEM 6.3 使用 OSGi R6 注释和 Sling 模型

javascript - 使用 Facebook 登录但仍然收到 : "Unauthenticated access is not supported for this identity pool"

java - Spring Security 注销未命中 success-handler-ref

swift - 如何使用 key 在 swift 4 中散列 sha256?

c++ - 为什么我没有得到正确的 sha256?

java - 一次设置多个按钮的样式 [Javafx]

java - mongodb游标异常 - Java