Создание и проверка подписи Gigya

Я написал метод для проверки подписи Gigya по заданной метке времени и UID, основанный на инструкциях Gigya по созданию подписи. Вот код Gigyapsuedoдля этого:

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

[sic]

Вот мой метод (обработка исключений опущена):

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

Этот метод возвращает false, даже если этого не должно быть. Может ли кто-нибудь обнаружить что-то не так с моей реализацией? Мне интересно, может ли быть проблема с вызывающим абонентом или самой гигией - "Ваш метод проверяется" является допустимым ответом.

Я использую класс Apache CommonsBase64для кодирования.

Дополнительную (несколько избыточную) информацию о подписях также можно найти в FAQ Gigyaна случай, если это поможет.

Чтобы прояснить это далее: uid, timestampи подписьберутся из файлов cookie, установленных gigya. Чтобы убедиться, что они не подделаны, я беру uidи временную меткуи убеждаюсь, что подписьможно реконструировать с помощью моего секретного ключа. Тот факт, что он терпит неудачу, когда он не должен, указывает на ошибку/проблему с форматом в какой-то момент процесса, либо с моим методом, либо во внешнем интерфейсе, либо с самой гигией. Цель этого вопроса состоит в том, чтобы исключить ошибку в приведенном выше методе.

Примечание:Я также пробовал URL-кодирование uid:

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

Хотя я не думаю, что это имеет значение, поскольку это просто целое число. То же самое касается timestamp.

Обновление:

Основная проблема решена, однако сам вопрос остается открытым. См. мой ответ для более подробной информации.

Обновление 2:

Оказалось, что я запутался в том, какой из классов Apache Base64я использовал — мой код использовал не версию кодека Commons , а . ] Версия Commons Net. Эта путаница возникла из-за большого количества сторонних библиотек в моем проекте и моего незнания многих Base64реализаций на протяжении многих лет из библиотек Apache - ситуация, как я теперь понимаю, Commons Codecпредназначалась для адрес. Похоже, я опоздал на вечеринку, когда дело доходит до кодирования.

После переключения на версию кодека Commons метод работает корректно.

Я собираюсь присудить награду @erickson, так как его ответбыл точным, но, пожалуйста, проголосуйте за оба ответа за их превосходное понимание! Я пока оставлю награду открытой, чтобы они получили то внимание, которого заслуживают.

10
задан 14 revs 23 May 2017 в 11:53
поделиться