Я написал метод для проверки подписи 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;
}
Вот мой метод (обработка исключений опущена):
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, так как его ответбыл точным, но, пожалуйста, проголосуйте за оба ответа за их превосходное понимание! Я пока оставлю награду открытой, чтобы они получили то внимание, которого заслуживают.