Код подтверждения получения в App Store для Mac? - PullRequest
39 голосов
/ 24 ноября 2010

Хотите знать, есть ли у кого-нибудь учебник или рабочий код для проверки квитанций в новом Mac App Store? О единственных ссылках, которые мне удалось найти, - это звездная документация Apple по этой теме и один проект с открытым исходным кодом, который компилируется, но не имеет много встроенных комментариев, так что это трудно понять, если вы не крипто-умник.

Документы Apple только для зарегистрированных разработчиков:

https://developer.apple.com/devcenter/mac/documents/validating.html

ValdiateStoreReceipt Родди (выглядит многообещающе, но редко документировано):

https://github.com/roddi/ValidateStoreReceipt

Также интересно, почему Apple не просто предоставляет рабочий код для проверки?

Есть еще какие-нибудь хорошие ссылки?

Ответы [ 13 ]

29 голосов
/ 30 октября 2011

Трудно предоставить общее решение для проверки квитанций в Mac App Store, в основном потому, что это очень чувствительный кусок кода, который трудно обойти (ср. документация Apple ).

Эти проекты GitHub являются очень хорошей отправной точкой, чтобы узнать, какие шаги необходимо выполнить при проверке квитанции:

Как только вы поняли, что нужно делать, вот несколько советов:

  • Не используйте классы или методы Objective-C. Objective-C несет много метаданных, и его динамическая природа подвергает их внедрению во время выполнения.
  • Используйте только вызовы функций C. Даже если вам нужно больше строк кода с каркасом CoreFoundation, вы можете прекрасно делать то, что умеет каркас Foundation (NSString, NSArray, NSDictionary, ...).
  • Не связывайте динамически с библиотекой OpenSSL , поскольку она устарела в Mac OS X Lion. Если вы хотите использовать OpenSSL , статически свяжите его, чтобы иметь последнюю версию.
  • Использование системных функций для криптографии. Mac OS X поставляется с эквивалентными функциями начиная с 10.5. Например, для вычисления хэша SHA-1 вы можете использовать функцию CC_SHA1 .
  • Не помещайте строки в открытый текст в вашем коде. Закодируйте их или зашифруйте их. Если вы этого не сделаете, вы дадите подсказку о местонахождении вашего кода.
  • Не используйте числовые константы в вашем коде. Вычислите их во время выполнения с помощью простых операций (+, -, / или *). Опять же, если вы этого не сделаете, вы дадите подсказку о местонахождении вашего кода.
  • Избегайте простых тестов для проверки, встраивая свои тесты и вызов NSApplicationMain в сложный цикл.
  • Избегайте прямого вызова NSApplicationMain. Используйте указатель на функцию, чтобы скрыть вызов. Если вы этого не сделаете, вы дадите подсказку о расположении вашего кода.
  • Для каждого выпуска вашего приложения слегка изменяйте код проверки, чтобы он никогда не совпадал.

Помните, что подтверждение квитанции необходимо и не так просто, как кажется. Это может занять много времени, которое вам лучше потратить на ваше приложение.

Поэтому я предлагаю вам взглянуть на это приложение: Receigen (Отказ от ответственности: я разработчик этого приложения).

6 голосов
/ 24 декабря 2010

Для проверки по реальной квитанции после тестирования измените эту строку кода в вашем main.m файле:

if (!validateReceiptAtPath(@"~/Desktop/receipt"))

на

#ifdef USE_SAMPLE_RECEIPT   // defined for debug version
    NSString *pathToReceipt = @"~/Desktop/receipt";
#else
    NSString *pathToReceipt = [[[NSBundle mainBundle] bundlePath]
        stringByAppendingPathComponent:@"Contents/_MASReceipt/receipt"];
#endif  
    if (!validateReceiptAtPath(pathToReceipt))
        exit(173); //receipt did not validate

и в настройках вашего компилятора «Другие флаги C» для вашей конфигурации отладки должны включать -DUSE_SAMPLE_RECEIPT

вежливость http://jesusagora.org/groups/futurebasic/0::53562:get:1read.html

5 голосов
/ 07 января 2011

Убедитесь, что вы проверяете квитанцию ​​для вашего приложения. Легко сделать всю криптографию и проверку подписей на неправильную квитанцию.

См. http://pastebin.com/1eWf9LCg, где, похоже, Angry Birds пропустили этот бит и оставили их открытыми для людей, заменяющих чек из бесплатного приложения.

Алан Кватермейн также имеет код для этого на github. https://github.com/AlanQuatermain/mac-app-store-validation-sample

Не следует использовать как есть, чтобы избежать автоматического удаления.

3 голосов
/ 07 февраля 2011

Вы можете попробовать NPReceiptVerification .Это самый простой способ добавить подтверждение получения в ваше приложение.Вы просто добавляете файлы классов в свой проект, устанавливаете версию и идентификатор пакета, а все остальное обрабатывается автоматически.

3 голосов
/ 13 января 2011

Я просмотрел код Alan Quartermain, и он выглядит хорошо. О чем подумать:

последний параметр здесь может / должен быть скомпилированным требованием о том, что код должен быть подписан ВАШИМ сертификатом, а не кем-либо еще.

Когда разработчик отправляет приложение в магазин на утверждение, сертификаты подписи выглядят следующим образом:

3rd Party Mac Developer Application: me
Apple Worldwide Developer Relations Certification Authority
Apple Root CA

После доставки приложения из App Store конечному пользователю сертификаты подписи выглядят следующим образом:

Apple Mac OS Application Signing
Apple Worldwide Developer Relations Certification Authority
Apple Root CA

Кроме того, я предлагаю выход только (173), когда квитанция отсутствует, но все остальное в порядке.

2 голосов
/ 04 мая 2013

Вы можете обратиться к RVNReceiptValidation , которое легко реализовать.Просто вам нужно установить идентификатор пакета в RVNReceiptValidation.m файле и версии вашего приложения.Не забудьте получить квитанцию ​​от Apple, вам нужно запустить приложение из Finder.Этот класс также помогает в реализации покупки InApp.

2 голосов
/ 30 июля 2011

Я бы предложил реализовать подпрограммы проверки кода как функции C , а не методы ObjC.

Этот метод делает (немного) труднее найти код проверки квитанции, так как в двоичный файл компилируется меньше имен методов.

1 голос
/ 08 января 2011

При создании образца квитанции из Apple Docs не добавляйте дополнительные символы после «end», иначе код uudecode не будет выполнен.

1 голос
/ 27 декабря 2010

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

0 голосов
/ 11 октября 2018

RVNReceiptValidation великолепен и использует CommonCrypto, а не устаревший в настоящее время Apple, openssl. вам придется приложить действительную квитанцию ​​к вашему проекту, чтобы отладить его. Сделайте это, получив действительный чек из другого пакета приложений, и создайте фазу сборки в своей тестовой среде, чтобы добавить ее в свой пакет. Я предлагаю следующие методы для запутывания:

Зашифруйте kRVNBundleID и kRVNBundleVersion и расшифруйте их при сравнении с CFBundleIdentifier и CFBundleShortVersionString.

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

static void testFunction(void);

typedef void (*functionPtr)(void);

functionPtr obfuscationArray[8] = {
    (functionPtr)0xA243F6A8,
    (functionPtr)0x885308D3,
    (functionPtr)0x13198A2E,
    (functionPtr)0x03707344,
    (functionPtr)0xA4093822,
    (functionPtr)0x299F31D0,
    (functionPtr)0x082EFA98,
    (functionPtr)0xEC4E6C89};

int main(int argc, const char * argv[]) {
    functionPtr myFuncPtr;

    obfuscationArray[3] = &testFunction;
    myFuncPtr = obfuscationArray[3];
    (myFuncPtr)();

    return 0;
}

static void testFunction(void){
    printf("function executed\n");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...