首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Java中验证Instagram实时API x集线器签名?

如何在Java中验证Instagram实时API x集线器签名?
EN

Stack Overflow用户
提问于 2013-12-18 12:54:07
回答 1查看 1.7K关注 0票数 0

我正在使用Play框架为Instagram实时API开发消费者。但是仍然不能正确地执行x中心签名验证。那么,我们如何使用Java和Play框架来执行Instagram x中心签名验证呢?

以下是我的当前代码:

  1. 在Play框架中,我使用以下方法获得JSON有效负载: 公开静态结果receiveInstaData(){ JsonNode json =JsonNode().body().asJson();//从报头//获取相应的客户端机密VerificationResult verificationResult =verificationResult clientSecret、json.toString()、xHubSignature;if(verificationResult.isSuccess()){ //do }}
  2. 然后在SubscriptionUtil内部,我使用以下代码执行验证: 公共静态VerificationResult(encodedResult.equals(xHubSignature),verifySubscriptionPostSignature(String clientSecret,String rawJsonData,String xHubSignature) { SecretKeySpec keySpec;keySpec =新SecretKeySpec(clientSecret.getBytes("UTF-8"),HMAC_SHA1);mac;Mac = Mac.getInstance(HMAC_SHA1);mac.init(keySpec);byte[]结果;return =keySpec(“UTF-8”);String en21=(结果);返回新;}

我创建了一个独立的Python脚本,它复制instagram-python实现,它们为相同的clientSecretjsonString生成相同的结果。也许我应该提供原始二进制数据而不是字符串。

如果我们需要一个用于JSON请求的原始二进制数据,那么我需要创建自定义BodyParser来将JSON请求解析为原始二进制data5

参考文献:

1-4 (所以不允许我发布超过2个链接,所以我把所有的参考在这里。链接包含Ruby、Python和PHP中的签名验证)

5

6我的独立python脚本:#!/usr/bin/env python

代码语言:javascript
运行
复制
import sys
import hmac
import hashlib

hc_client_secret = "myclientsecret"
hc_raw_response = "[{\"subscription_id\":\"1\",\"object\":\"user\",\"object_id\":\"1234\",\"changed_aspect\":\"media\",\"time\":1297286541},{\"subscription_id\":\"2\",\"object\":\"tag\",\"object_id\":\"nofilter\",\"changed_aspect\":\"media\",\"time\":1297286541}]"

client_secret = hc_client_secret
raw_response = hc_raw_response

if len(sys.argv) != 3:
    print 'Usage verify_signature <client_secret> <raw_response>.\nSince the inputs are invalid, use the hardcoded value instead!'
else:
    client_secret = sys.argv[1]
    raw_response = sys.argv[2]  

print "client_secret = " + client_secret
print "raw_response = " + raw_response

digest = hmac.new(client_secret.encode('utf-8'), msg=raw_response.encode('utf-8'), digestmod=hashlib.sha1).hexdigest()
print digest
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-24 14:00:36

最后,我设法找到了解决办法。对于Play框架中的Controller,我们需要使用BodyParser.Raw,这样我们就可以将有效负载请求提取为原始数据,即字节数组。

以下是Play Framework中控制器的代码:

代码语言:javascript
运行
复制
@BodyParser.Of(BodyParser.Raw.class)
public static Result receiveRawInstaData(){
    Map<String, String[]> headers = request().headers();
    RawBuffer jsonRaw = request().body().asRaw();

    if(jsonRaw == null){
        logger.warn("jsonRaw is null. Something is wrong with the payload");
        return badRequest("Expecting serializable raw data");
    }

    String[] xHubSignature = headers.get(InstaSubscriptionUtils.HTTP_HEADER_X_HUB_SIGNATURE);
    if(xHubSignature == null){
        logger.error("Invalid POST. It does not contain {} in its header", InstaSubscriptionUtils.HTTP_HEADER_X_HUB_SIGNATURE);
        return badRequest("You are not Instagram!\n");
    }

    String json;
    byte[] jsonRawBytes;

    jsonRawBytes = jsonRaw.asBytes();
    json = new String(jsonRawBytes, StandardCharsets.UTF_8);

    try {
        String clientSecret = InstaSubscriptionUtils.getClientSecret(1);
        VerificationResult verificationResult = SubscriptionUtil.verifySubscriptionPostRequestSignature
                (clientSecret,jsonRawBytes, xHubSignature[0]);
        if(verificationResult.isSuccess()){
            logger.debug("Signature matches!. Received signature: {}, calculated signature: {}", xHubSignature[0], verificationResult.getCalculatedSignature());
        }else{
            logger.error("Signature doesn't match. Received signature: {}, calculated signature: {}", xHubSignature[0], verificationResult.getCalculatedSignature());
            return badRequest("Signature does not match!\n");
        }
    } catch (InstagramException e) {
        logger.error("Instagram exception.", e);
        return internalServerError("Internal server error. We will attend to this problem ASAP!");
    }

    logger.debug("Received xHubSignature: {}", xHubSignature[0]);
    logger.info("Sucessfully received json data: {}", json);

    return ok("OK!");
}

以及方法verifySubscriptionPostRequestSignatureSubscriptionUtil中的代码

代码语言:javascript
运行
复制
public static VerificationResult verifySubscriptionPostRequestSignature(String clientSecret, byte[] rawJsonData, String xHubSignature) throws InstagramException{
    SecretKeySpec keySpec;
    keySpec = new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), HMAC_SHA1);
    Mac mac;

    try {
        mac = Mac.getInstance(HMAC_SHA1);
        mac.init(keySpec);
        byte[] result = mac.doFinal(rawJsonData);
        String encodedResult = Hex.encodeHexString(result);

        return new VerificationResult(encodedResult.equals(xHubSignature), encodedResult);
    } catch (NoSuchAlgorithmException e) {
        throw new InstagramException("Invalid algorithm name!", e);
    } catch (InvalidKeyException e){
        throw new InstagramException("Invalid key: " + clientSecret, e);
    }
}

我在jInstagram中实现了这个解决方案,下面是指向源代码的链接:SubscriptionUtil

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20658813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档