Android InApp Billing — для чего на самом деле нужны одноразовые номера?

ДА, я прочитал всю документацию @developer.android.com и все понял, за одним исключением — для чего это было введено.

Поскольку все ответы на заказы из Google Play подписываются недоступным для всех закрытым ключом и проверяются парным открытым ключом (в моем случае на внешнем сервере, поэтому он также недоступен для третьего лица), просто (почти) нет способа подделка.

Все эти одноразовые номера — просто лишний способ обезопасить покупки. Более того, в документах ничего не сказано о ситуации, когда:

  1. Я покупаю товар;
  2. Создайте одноразовый номер и отправьте его в Google Play;
  3. Произойдет сбой, так что все мои известные одноразовые номера будут потеряны;
  4. Перезапустите мое приложение и получите обратный вызов от Google Play;
  5. ...И отклонить этот вызов из-за того, что он не распознал одноразовый номер!

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

ИМХО кто-то только что сказал: «Эй, процесс верификации слишком прост, давайте добавим что-то еще со случайностью, это будет намного круче!». Так кто-то сделал.

Или вы не могли бы открыть мне глаза на какой-то другой вариант использования, который я пропустил? В противном случае я удаляю всю часть nonces из своего кода.


person Fenix Voltres    schedule 09.05.2012    source источник
comment
Если покупками управляют, помните, что всегда есть возможность восстановить покупки, которые понадобятся пользователям, если они когда-либо 1. приобретут новое устройство, 2. вернут устройство к заводским настройкам.   -  person weston    schedule 09.05.2012
comment
Вы правы, я забыл о них, так как у меня их нет, но как это связано с одноразовыми номерами?   -  person Fenix Voltres    schedule 09.05.2012
comment
Просто ваш пользователь платит за товар и никогда не получает его. Сценарий не является проблемой, если вы используете управляемые покупки, поэтому в этом случае не нужно беспокоиться о потере одноразовых номеров. Я не утверждаю, что это ответ, просто комментарий!   -  person weston    schedule 09.05.2012


Ответы (4)


Вам не нужно сохранять одноразовый номер «на диск» для учета сбоя приложения.

Когда ваше приложение выйдет из строя, да, вы потеряете свой список известных одноразовых номеров. Однако, когда ваше приложение перезапускается и вы получаете IN_APP_NOTIFY, вам нужно будет выполнить еще одно GET_PURCHASE_INFORMATION, когда вы сделаете это GET_PURCHASE_INFORMATION, вы создадите новый одноразовый номер и добавите его в список известных одноразовых номеров.

Что вы должны помнить, так это то, что одноразовый номер один для каждого GET_PURCHASE_INFORMATION (который возвращает вам несколько купленных предметов), а не один одноразовый номер для каждого купленного предмета.

Как вы сказали, вы реализовали свой собственный способ избежать повторных атак, но использование одноразового номера является одним из таких безопасных методов.

person Blundell    schedule 16.08.2012
comment
Что ж, спасибо, я думаю, вы попали в яблочко. Nonces следует рассматривать как один из многих способов справиться с ответной атакой, если вы не проверяете что-то другое уникальное, т.е. е. orderId в JSON (что намного лучше, ИМХО). Но в моем случае они бесполезны. - person Fenix Voltres; 16.08.2012

Вы должны сохранять сгенерированные одноразовые номера перед их отправкой. Приложения для Android могут зависнуть или закрыться в любой момент, поэтому в целом все должно быть сохранено.

Причина использования одноразовых номеров заключается в предотвращении повторных атак. Я далек от квалификации, чтобы ответить, нужно ли использовать одноразовый номер или нет, но я предполагаю, что это не просто так.

person richardwiden    schedule 09.05.2012
comment
Я сохраняю их в памяти, сохраняю на локальном диске, чтобы другие могли читать/подделывать/что угодно. Мне не нужно беспокоиться об ответных атаках, потому что, как я уже упоминал, асимметричные ключи достаточно безопасны, чтобы я мог быть уверен, что никто ничего не подделал. - person Fenix Voltres; 09.05.2012
comment
С точки зрения безопасности на диске не отличается от в памяти. Если ваш телефон рутирован, приложения будут иметь доступ к обоим. Если бы они НЕ были рутированы, им пришлось бы использовать ошибки безопасности, чтобы получить к ним доступ. - person richardwiden; 09.05.2012
comment
Вы хотите сказать своим пользователям, что вы ДУМАЕТЕ, что ВАШ подход ДОСТАТОЧНО безопасен? - person richardwiden; 09.05.2012
comment
Извините, но вы совершенно не правы - рутируя устройство, можно получить доступ к файлам на диске, но не может иметь доступ к частной памяти, выделенной для приложения - у каждого процесса есть своя собственная виртуальная машина Dalvik, система управления памятью linux также защищает ее . @2 комментарий - слова, слова. Должен ли я показать вам математическое доказательство того, каковы шансы пользователя обмануть асимметричные ключи? Тем не менее, я хотел бы услышать что-нибудь о nonces. :) - person Fenix Voltres; 09.05.2012
comment
Безопасность в этой области не является проблемой для пользователя. Если у вас есть дыра в вашей логике, вы просто потеряете деньги из-за пиратства, это не повлияет на карман законных пользователей. - person weston; 09.05.2012

Представьте, что ваш пользователь покупает товар, скажем, за 100 долларов. Ваше приложение получает уведомление о том, что доступны платежные данные, приложение запрашивает данные, а AppStore отвечает PURCHASE_STATE_CHANGED. Пользователь записывает сообщение (!) из AppStore и сохраняет его.

Позже пользователь подделывает уведомление вашему приложению, сообщая ему, что платежные данные доступны (любой может подделать это, поскольку это уведомление не подписано). Приложение думает: «О, эй, может быть, я просто упал и потерял всю информацию о покупке, которую только что сделал мой пользователь!? Посмотрим, что скажет AppStore». Поэтому он запрашивает данные из магазина приложений. Пользователь прерывает этот запрос и отправляет ранее записанное сообщение в ваше приложение. Приложение видит сообщение, проверяет его и считает, что оно действительно (потому что оно подписано и все такое). Таким образом, приложение даст вам еще один ценный предмет на 100 долларов. И другой. Столько раз, сколько пользователь воспроизводит записанное сообщение. Поэтому называется: повторная атака.

Однако есть одна вещь, которая предотвращает такую ​​атаку: одноразовый номер. Если ваше приложение отправляет одноразовый номер в своем запросе платежных данных, оно ожидает получить тот же одноразовый номер в ответе PURCHASE_STATE_CHANGED. Поскольку одноразовый номер используется только один раз, вы не можете воспроизвести ранее записанные сообщения, поскольку они не будут совпадать с одноразовым номером, использованным в запросе.

person Thomas Hilbert    schedule 25.06.2012
comment
Это не совсем так. Приведенная вами схема хороша, но все равно не показывает, для чего нужны одноразовые номера - я знаю о такой проблеме, как ответная атака, но решаю ее по-другому - я проверяю ответ Google Play на мой внешний сервер, где я храню свой открытый ключ. Более того, чтобы избежать такой ситуации, о которой вы упомянули, каждый раз, когда я это делаю, я сохраняю уникальный идентификатор заказа, который приходит в подписанном JSON - его нельзя подделать, потому что он подписан и гарантированно уникален. Я просто игнорирую 2-е сообщение с тем же идентификатором заказа. Кажется, одноразовые номера действительно бесполезны (даже более того - вредны, как я уже сказал). - person Fenix Voltres; 27.06.2012

«Ононс действует как соль для транзакции, аналогично тому, как системы *nix хранят пароли. той же подписи и других подобных криптографических атак».

см. ответ от кесо

person OferR    schedule 22.07.2012