构建和验证的Gigya签名 [英] Constructing and validating a Gigya signature

查看:199
本文介绍了构建和验证的Gigya签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个方法来对指定的时间戳和UID的基础上的Gigya的<一个验证的Gigya签名href=\"http://developers.gigya.com/030_Gigya_Socialize_API_2.0/010_Developer_Guide/57_Security#Constructing_a_signature\">instructions构建签名。这里是的Gigya的 code这样做是:

I wrote a method to verify a gigya signature against a specified timestamp and UID, based on Gigya's instructions for constructing a signature. Here is Gigya's psuedo code for doing that:

string constructSignature(string timestamp, string UID, string secretKey) {
    // Construct a "base string" for signing
    baseString = timestamp + "_" + UID;
    // Convert the base string into a binary array
    binaryBaseString = ConvertUTF8ToBytes(baseString);
    // Convert secretKey from BASE64 to a binary array
    binaryKey = ConvertFromBase64ToBytes(secretKey);
    // Use the HMAC-SHA1 algorithm to calculate the signature 
    binarySignature = hmacsha1(binaryKey, baseString);
    // Convert the signature to a BASE64
    signature = ConvertToBase64(binarySignature);
    return signature;
}

<一个href=\"http://stackoverflow.com/questions/10033963/constructing-and-validating-a-gigya-signature#comment12987098_10033963\">[sic]

下面是我的方法(异常处理省略):

Here's my method (exception handling omitted):

public boolean verifyGigyaSig(String uid, String timestamp, String signature) {

    // Construct the "base string"
    String baseString = timestamp + "_" + uid;

    // Convert the base string into a binary array
    byte[] baseBytes = baseString.getBytes("UTF-8");

    // Convert secretKey from BASE64 to a binary array
    String secretKey = MyConfig.getGigyaSecretKey();
    byte[] secretKeyBytes = Base64.decodeBase64(secretKey);

    // Use the HMAC-SHA1 algorithm to calculate the signature 
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(new SecretKeySpec(secretKeyBytes, "HmacSHA1"));
    byte[] signatureBytes = mac.doFinal(baseBytes);

    // Convert the signature to a BASE64
    String calculatedSignature = Base64.encodeBase64String(signatureBytes);

    // Return true iff constructed signature equals specified signature
    return signature.equals(calculatedSignature);
}

此方法返回,即使它不应该。任何人都可以发现有毛病我执行?我不知道是否有可能与主叫方或本身的Gigya一个问题 - 你的方法检查出来是一个有效的答案

This method is returning false even when it shouldn't. Can anyone spot something wrong with my implementation? I'm wondering if there could be an issue with the caller or gigya itself - "Your method checks out" is a valid answer.

我使用Apache <一个href=\"http://commons.apache.org/$c$cc/apidocs/org/apache/commons/$c$cc/binary/Base64.html\"><$c$c>Base64类编码。

另外(有些多余)上签名信息也是在的Gigya的常见问题解答发现,如果没有什么帮助。

Further (somewhat redundant) info on signatures is also found in Gigya's FAQ, in case that helps.

为了澄清这进一步 UID 时间戳签名都正在采取由的Gigya设置cookies。为了验证这些不被欺骗,我正在 UID 时间戳,并确保签名可以用我的密钥被重建。的事实,即当它不应该在过程中的某些点指示一个错误/格式问题失败,无论是与我的方法中,在前端,或具有的Gigya本身。这个问题的目的实质上是排除错误上述方法。

To clarify this further: uid, timestamp, and signature are all being taken from cookies set by gigya. In order to verify these aren't being spoofed, I'm taking uid and timestamp, and making sure signature can be reconstructed using my secret key. The fact that it fails when it shouldn't indicates a bug/format issue at some point in the process, either with my method, in the front-end, or with gigya itself. The purpose of this question is essentially to rule out a bug in the above method.

注意:URL编码我也试过 UID

String baseString = timestamp + "_" + URLEncoder.encode(uid, "UTF-8");

虽然我不认为这会管用,因为它只是一个整数。这同样适用于时间戳

更新:

根本的问题已经解决,但是这个问题本身仍然开放。请参见我的回答了解更多详情。

The underlying issue has been solved, however the question itself remains open. See my answer for more details.

更新2:

原来我是混淆有关的Apache的的Base64 我用的是类 - 我的code的未使用的Commons codeC版本不过的Commons网版本。这种混乱从我的项目的大量第三方库和我从Apache库的诸多的Base64 实现的无知多年来出现了 - 这种情况我现在意识到的Commons codeC 是为了解决。看起来像我迟到了,当涉及到编码。

It turns out I was confused about which of apache's Base64 classes I was using - my code was not using the Commons Codec version but the Commons Net version. This confusion arose from my project's large amount of third-party libraries and my ignorance of the many Base64 implementations over the years from Apache libraries - a situation I now realize Commons Codec was meant to address. Looks like I'm late to the party when it comes to encoding.

在下议院codeC的版本切换之后,该方法行为正确。

After switching in Commons Codec's version, the method behaves correctly.

我要奖赏金 @erickson 以来的他的回答是现货,但请给予好评两种答案的出色的洞察力!我会离开赏金开放的现在,使他们得到应有的重视。

I'm going to award the bounty to @erickson since his answer was spot on, but please upvote both answers for their excellent insight! I'll leave the bounty open for now so they get the attention they deserve.

推荐答案

好吧,我终于听到的Gigya回到昨天就这个问题,原来自己的服务器端Java API公开的方法来处理这​​个用例,<一个href=\"http://wikifiles.gigya.com/SDKs/Java/doc/com/gigya/socialize/SigUtils.html#validateUserSignature%28java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String%29\"><$c$c>SigUtils.validateUserSignature:

Well I finally heard back from gigya yesterday regarding this issue, and it turns out their own server-side Java API exposes a method for handling this use case, SigUtils.validateUserSignature:

if (SigUtils.validateUserSignature(uid, timestamp, secretKey, signature)) { ... }

今天我能够证实这一呼吁是正确的行为,因此,解决眼前的问题,并把这个整个后变成一种一捂脸时刻对我来说。

Today I was able to verify that this call is behaving correctly, so that solves the immediate issue and turns this whole post into a kind of a facepalm moment for me.

但是:

我在为什么我自己的家热轧方法不起作用仍然有兴趣(和我有一个赏金,奖励反正)。我将在下周再次审视它,并将它与 SigUtils 类文件进行比较,试图找出什么地方出了错。

I'm still interested in why my own home-rolled method doesn't work (and I have a bounty to award anyway). I'll examine it again this coming week and compare it with the SigUtils class file to try and figure out what went wrong.

这篇关于构建和验证的Gigya签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆