我正在使用 Facebook 并使用 Sun Base64 解码器在 Java servlet 中解析签名请求。尽管签名似乎几乎匹配,但我遇到了签名失败。我无法弄清楚为什么它不完全匹配,我相信这一定是我的代码有问题。查看我在做什么的最少代码:
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 请求的新手,所以我必须相信我在代码中遗漏了一些东西,但我没有看到它,并且已经玩了足够长的时间来需要帮助。而且我在网上其他任何地方都没有看到答案。谢谢!