Биллинг в приложении Android: Security.java сообщает, что проверка подписи не удалась

Я реализовал тестовое приложение с биллингом в приложении Android. Я заполнил свой открытый ключ в файле Security.java. Все работает, но когда я отправляю платеж, приложение вылетает. Я получаю сообщение об ошибке в LogCat с надписью «Ошибка проверки подписи», что соответствует этому фрагменту кода:

if (!sig.verify(Base64.decode(signature))) {
                Log.e(TAG, "Signature verification failed.");
                return false;
}

Если я изменю этот бит, чтобы он возвращал true, а не false, тогда все работает правильно — я могу отправить платеж и безопасно вернуться в приложение — но я предполагаю, что что-то еще не так, так как я, вероятно, должен изменить это, чтобы вернуть true.

Любые идеи о том, что может быть причиной этого?


person Chris    schedule 15.08.2011    source источник


Ответы (5)


Эта ошибка проверки подписи может быть вызвана:

1.- Неверный открытый ключ. Возможно, вы забыли скопировать какой-то символ. Бывает :)

2.- APK должен быть подписан. Вы не можете использовать debug.keystore, если вы это сделаете, ваша строка подписи будет пустой.

И помните, для тестирования биллинга в приложении:

  • Добавьте открытый ключ Android Market в Security.java (String base64EncodedPublicKey = "your public key here")

  • Создайте в режиме выпуска и подпишите его (если вы используете Eclipse, вы можете использовать мастер экспорта).

  • Загрузите релизную версию на Android Market, не публикуйте ее и создайте список продуктов.

  • Установите приложение на свое устройство ( adb -d install myapp.apk ) и сделайте тестовую учетную запись основной на своем устройстве.

person gergonzalez    schedule 08.02.2012
comment
APK-файл, который вы отправляете на свое тестовое устройство, также должен иметь ТОЧНО те же значения версии, что и APK-файл, который вы загрузили в Developer Console. Обновление версии APK консоли разработчика может занять до 6 часов. - person Cory Trese; 06.11.2013
comment
На сегодняшний день параметр base64PublicKey передается в IabHelper, он не определен в Security.java. - person 18446744073709551615; 20.11.2013
comment
Нет ли более простого способа разработать поток интеграции биллинга без подписи, загрузки, ожидания и т. д.? Я согласен с тем, что тестирование должно проводиться как можно ближе к производству, но цикл разработки слишком долгий. Если я по ошибке сделал неверный if или NPE, мне нужно заново пройти всю фазу публикации! - person AlikElzin-kilaka; 16.12.2013
comment
Я поражен, что Google до сих пор не улучшил это. Тонны кода, очень сложный и многое может пойти не так. Это должно быть очень просто для интеграции. Также они не исправляют открытые проблемы, отправленные в исходный проект. - person powder366; 30.05.2014

В моем случае была хорошо скрытая проблема.

Когда я впервые настроил биллинг в приложении, я попробовал статические ответы и купил элемент android.test.purchased. Когда я переключился на производственные товары и попытался запросить инвентарь, этот поддельный продукт стал причиной всех моих проблем.

Итак, в этом случае решение состояло в том, чтобы удалить поддельный продукт из моего собственного предмета.

Просто добавьте в файл IABHelper.java этот фрагмент:

                Purchase p = new Purchase(itemType, purchaseData, signature);
                try {
                    consume(p);
                } catch (IabException e) {
                    e.printStackTrace();
                }

в операторе else метода, имеющего эту подпись:

int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException

После очистки ваших собственных элементов вернитесь к исходному вспомогательному java-файлу. Конечно, это только для стадии разработки.

person Francesco Donzello    schedule 30.11.2013
comment
Работает как чудо. Еще одна ошибка в In-App Billing. - person X. Wo Satuk; 03.07.2014
comment
Эта проблема все еще сохраняется в текущей версии биллинга Google. В основном android.test.purchased не работает; После того, как вы купите android.test.purchased, функция verifyPurchase в Security.java всегда будет давать сбой, а QueryInventoryFinishedListener остановится на строке if (result.isFailure()); это связано с тем, что элемент android.test.purchased всегда не проходит проверку TextUtils.isEmpty(signature) в Security.java, поскольку он не является реальным элементом и не имеет подписи, возвращаемой сервером. - person MPaulo; 11.09.2014
comment
... а также помечайте свои продукты в приложениях как АКТИВНЫЕ, когда вы запрашиваете их - person appsthatmatter; 03.02.2016
comment
Вы, сэр, чудотворец. Какая вопиюще загадочная проблема, давно пора исправлять!! - person dooleyo; 06.01.2017

В моем случае я вставил неправильный открытый ключ с тем же префиксом и суффиксом. Просто убедитесь на 100%, что это правильно.

person rensq    schedule 18.08.2015
comment
Спасибо, вы меня спасли! Та же проблема - клавиши очень похожи, но разные для разных приложений - person Dmitry; 09.09.2018

Мой ответ может быть полезен кому-то в будущем

Убедитесь, что в вашем приложении используется правильный base64EncodedPublicKey.

person shyam    schedule 11.10.2018

Как было сказано ранее, я использовал неправильный base64EncodedPublicKey.

Вы можете найти его в консоли Google Play, на вкладке приложения, перейдите на вкладку Настройка монетизации и скопируйте его.

person jas-chu    schedule 26.05.2021