Форум программистов, компьютерный форум CyberForum.ru

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
#1

Безопасность платного приложения - Objective-C

18.07.2013, 12:44. Просмотров 1324. Ответов 17
Метки нет (Все метки)

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

В данном случае рассматривается приложение, которое осуществляются покупки через StoreKit

Если скажем что сам api storekit как бы дырок не содержит, то вот хранение "статусов" покупки в тех же NSUserDefaults вызывает беспокойство, что их можно подменить и заставить приложение думать что уже все куплено.

Могу предложить лишь шифрование всех ключей покупок через md5 с солью, что может хоть както противостоять подмене NSUserDefaults, если она возможна.

----

Вопрос есть ли еще какие либо методы хранения данной информации кроме NSUserDefaults?
И насколько NSUserDefaults являются надежным хранилищем впринципе?

Добавлено через 33 минуты
Так, тучи уже рассеиваются

инструмент для получения уникальных ключей устройства

Objective-C
1
[[UIDevice currentDevice] uniqueIdentifier];
Однако он уже устарел начиная с ios5 то есть не подходит

в ios6

Objective-C
1
[[[UIDevice currentDevice] identifierForVendor] UUIDString];
Но не работает в ios5, опять не подходит

Еще есть смесь из хеша названия бандла (папки) приложения и MAC адреса

https://github.com/gekitz/UIDevice-w...fier-for-iOS-5

Objective-C
1
2
[[UIDevice currentDevice] uniqueDeviceIdentifier];
[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier];
совместимо в ios5+ , как раз то что нужно

--
можно проверять содержимое NSUserDefaults на соответствие хешей посоленных с uniqueDeviceIdentifier.
Это существенно поднимает уровень сохранности данных на предмет взлома.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.07.2013, 12:44     Безопасность платного приложения
Посмотрите здесь:

Публичный ключ для платного приложения - Программирование Android
Недавно увидел что Янедекс открыл свой googleplay. и что меня порадовало там бесплатная регистрация. Хочу разместить платное приложение -...

Безопасность приложения - C#
Добрый вечер. Хотелось бы узнать как можно максимально обезопасить свое приложение. Допустим, мне нужно сохранить пароль, используемый...

Безопасность приложения - C#
Добрый день коллеги! Суть проблемы такова: Требуется организовать безопасность приложения на основе ролей(RBAC). Приложение...

Безопасность приложения c#+.net - C#
На сколько безопасно приложение на нет с точки зрения открытости кода. Сложно ли декомпилить программу и украсть к примеру пароль...

Безопасность PHP приложения. - PHP
Добрый вечер. Настал тот день и тот час, когда мою систему на PHP нужно выложить в сеть. Система возьмет на себя довольно...

Безопасность приложения: хранение в коде паролей к бд сервера - C#
Хочу из клиента на прямую подключаться к базе. Данные для подключения придется хранить где то в программе. Как сделать так чтобы...

Выбор платного хостинга - Выбор хостинга
Заканчиваю небольшой проект, а именно каталог статей, построенный на системе управления WordPress. Нужно определиться с выбором хостинга....

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
18.07.2013, 12:57     Безопасность платного приложения #2
KeyСhain подходит
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
18.07.2013, 13:15     Безопасность платного приложения #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ай, скажите НЕТ хранению чего либо важного в NSUserDefaults!
Никогда, даже не думайте об этом. Прислушайтесь к mobidevelop'у. Но это "темная" сторона keyChain.

Хранение чего-то там с appstore в keychain тоже имеет свои минусы. Ибо эта информация для приложения, но никак не для девайса.
"хранение статусов" уже за вас сделано на сервере Apple под учеткой пользователя.
Если вы переустановили приложение - есть функция restore. Если не Интернета - это проблемы пользователя.
По хорошему - эта инфа не должна быть у пользователя. Если у Вас есть такие проблемы c хранением - значит ваше приложение должно иметь связть с Вашим же сервером, на котором вся инфа о покупках и лежит.
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
18.07.2013, 13:21     Безопасность платного приложения #4
Кстати, да. zulkis прав. Статусы покупок хранятся яблочными серверами. И у них в любой момент можно осведомиться о том или ином айтеме. Или, может быть, мы вопрос неправильно поняли? Поясните задачу.
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
23.07.2013, 21:17  [ТС]     Безопасность платного приложения #5
извиняюсь за долгое отсутствие,
Статусы покупок хранятся яблочными серверами. И у них в любой момент можно осведомиться о том или ином айтеме.
хранят они, это верно, однако если приложение должно работать еще в "оффлайн" режиме. То где хранить информацию о покупках если в не NSUserDefaults ?

KeyСhain подходит
пока не пробовал, а стоит ли? они же могут хранить просто ключ какой нибудь.
заметь я не спрашиваю о хранении 10000 или 100000 элементов в массиве , а просто ключ из ~50 символов
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
24.07.2013, 07:19     Безопасность платного приложения #6
Прислали 1 раз данные с сервера, программа преобразовала себе это в информацию, записала что-то. И юзер этим пользуется. И без разницы онлайн или оффлайн.
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
24.07.2013, 09:36  [ТС]     Безопасность платного приложения #7
Прислали 1 раз данные с сервера, программа преобразовала себе это в информацию, записала что-то. И юзер этим пользуется. И без разницы онлайн или оффлайн.
так значит записала, и непременно в NSUserDefaults
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
24.07.2013, 12:44     Безопасность платного приложения #8
Да забудьте вы NSUserDefaults.
Например вы покупаете новые книжки.
Вот купили вы книжку, которой у Вас физически на девайсе нет.
Купили - скачали на сервер, положили ее pathUrl в базу, а саму книжку в cache.
И все, работайте с ней, она у Вас есть. Неважно есть ли интернет.
А если переустановите приложение - все равно нужен будет интернет. Хотя бы для скачивания самого приложения.
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
24.07.2013, 13:02  [ТС]     Безопасность платного приложения #9
короче будь то книжки или ссылки, сохранение данных имеет место быть так или иначе.
Vorona
Peace 2 all shining faces
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
24.07.2013, 15:14     Безопасность платного приложения #10
для хранения данных используется база данных
для секьюрности - шифрование, а вообще на сервере все лежит, а вы юзаете какой-то снепшот и временное хранилище в виде бд
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
26.07.2013, 13:29  [ТС]     Безопасность платного приложения #11
короче, так как записи данных не избежать, то можно применить AES шифрование словаря

файлы
NSData-AES.h

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
//  NSData-AES.h
//  Encryption
//
//  Created by Jeff LaMarche on 2/12/09.
//  Copyright 2009 Jeff LaMarche Consulting. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@interface NSData(AES)
- (NSData*)AES256EncryptWithKey:(NSString*)key;
 
- (NSData*)AES256DecryptWithKey:(NSString*)key;
@end
NSData-AES.m
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//
//  NSData-AES.m
//  Encryption
//
//  Created by Jeff LaMarche on 2/12/09.
//  Copyright 2009 Jeff LaMarche Consulting. All rights reserved.
//
 
#import "NSData-AES.h"
#import <CommonCrypto/CommonCryptor.h>
 
@implementation NSData(AES)
 
 
- (NSData*)AES256EncryptWithKey:(NSString*)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize           = dataLength + kCCBlockSizeAES128;
    void* buffer                = malloc(bufferSize);
    
    size_t numBytesEncrypted    = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    
    if (cryptStatus == kCCSuccess)
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}
 
- (NSData*)AES256DecryptWithKey:(NSString*)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize           = dataLength + kCCBlockSizeAES128;
    void* buffer                = malloc(bufferSize);
    
    size_t numBytesDecrypted    = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);
    
    if (cryptStatus == kCCSuccess)
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}
 
@end
использование через впомогательные функции распаковки

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma mark WriteRead Dict Secur
 
-(NSMutableDictionary *)readDictionaryFromFile:(NSString *)path withSecurKey:(NSString *)key {
    NSData*d = [NSData dataWithContentsOfFile:path];
    if (d) {
        d = [d AES256DecryptWithKey:key];
        if (d) {
            NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:d];
            if (dict) {
                 // полное мутирование словаря
                 NSMutableDictionary* mudict = CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (__bridge CFPropertyListRef)(dict), kCFPropertyListMutableContainers));
                return mudict;
            }
        }
    }
    return [NSMutableDictionary new];
}
 
-(bool)writeDictionary:(NSDictionary *)dict toFile:(NSString *)path withSecurKey:(NSString *)key {
    NSData*dt = [NSKeyedArchiver archivedDataWithRootObject:dict];
    dt = [dt AES256EncryptWithKey:key];
    return [dt writeToFile:path atomically:YES];
}
пример кода

Objective-C
1
2
3
4
// << чтение
NSMutableDictionary *dict = [self readDictionaryFromFile:@"Путь к файлу" withSecurKey:@"ключ шифрования"];
// << запись
[self writeDictionary:dict toFile:@"Путь к файлу" withSecurKey:@"ключ шифрования"];
Vorona
Peace 2 all shining faces
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
26.07.2013, 15:26     Безопасность платного приложения #12
а можете объяснить, что вами движет, когда вы вместо простого статического метода, который принимал бы на вход NSData и ключ, создаете категорию?

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

оно конечно красиво выглядит, но не всегда интуитивно понятно, что за какими-то утилитками можно лезть в сам объект, так как изначально там такой функциональности нету

просто интересно
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
26.07.2013, 16:49  [ТС]     Безопасность платного приложения #13
который принимал бы на вход NSData и ключ, создаете категорию
это всего лишь копия NSData+AES с просторов инета

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

Все что выше это просто исходник, никто не мешает его переделать в более удобный вид.
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
26.07.2013, 16:51     Безопасность платного приложения #14
Цитата Сообщение от noname_club Посмотреть сообщение
я больше склонен создавать 1 класс, включающий все категории для всех классов, которые этого требуют
Это как?
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
26.07.2013, 16:56  [ТС]     Безопасность платного приложения #15
Это как?
типа такого

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@interface NSArray (ArrayExt)
 
-(id) index: (int) ind;
-(void) cu_log;
-(NSString*) cu_implode: (NSString*) delemitter;
 
-(NSArray*) cu_preg_filter: (NSString*) filter
                     value: (id) value;
 
-(NSMutableArray*) cu_SortByDictionaryField: (NSString*) fieldname;
 
 
@end
 
 
@interface NSMutableArray (ArrayMuExt)
 
-(void) add: (id) object;
-(void) cu_SortAsStringArray;
-(void) cu_SortAsNumberArray;
-(void) cu_SortAsIntegerArray;
-(void) cu_Reverse;
 
@end
 
// расширенная строка
 
@interface NSString (StringExt)
 
-(NSMutableArray*) cu_explode: (NSString*) delemitter
                        empty: (bool) empty;
 
-(bool) cu_preg_match:(NSString*) filter
                value: (id) value;
 
-(NSString*) cu_trim;
 
-(NSString*) cu_translit;
 
-(NSString*) cu_htmlstriptags;
 
-(NSString*) cu_replace: (id) findstring
                   with: (id) replacer;
 
-(NSString*) cu_charAtIndex: (int) index;
 
-(NSString*) cu_substringFrom: (int) from
                       length: (int) length;
 
-(NSString*) cu_extractFileName;
 
-(void) cu_log;
 
-(NSString*) cu_ReverseString;
 
-(NSString*) cu_str_pad_left:(NSString*) str
                    length: (int) length;
 
@end
ну и соответвенно в m файле структура идентичная, перечисление описания работы категорий
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
26.07.2013, 16:59     Безопасность платного приложения #16
Ой, ну зачем я спросил?
noname_club
102 / 90 / 9
Регистрация: 01.05.2013
Сообщений: 583
26.07.2013, 17:04  [ТС]     Безопасность платного приложения #17
Ой, ну зачем я спросил?
если на то пошло, в h файлах Foundation применяется похожий метод. Категории, особенно для словарей и массивов тупо свалены друг за другом в 1 заголовочном файле. Так что ничего необычного.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.07.2013, 19:03     Безопасность платного приложения
Еще ссылки по теме:

Использование платного шаблона - WordPress
Всем доброго времени суток! Уважаемые, подскажите, пожалуйста, чем грозит использование платной темы(шаблона) без ее покупки? То есть я,...

Почта платного хостинга - Web-серверы
Всем привет. Дико заранее извиняюсь, если не туда написал, но просто не знал в какой раз дел писать. В общем, у меня такой вопрос. У меня...

Создание платного живого журнала - Web
Добрый день! Мне нужны Ваши ценные советы! У меня стоит задача создать сайт «живой журнал», на который можно подписаться за месяц за N...

Партнерство по созданию и поддержке платного киносайта - Предложения работодателей
Партнера по созданию и поддержке платного киносайта (тов) ищу. Предпочтение проживающим Москва и обл. От вас – написание скрипта движка...

Создание платного доступа на сайте язык РНР - PHP
Подскажите, как можно организовать платный доступ на сайте по дате. Принцип такой: 1. пользователь регистрируется на сайте (данные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
26.07.2013, 19:03     Безопасность платного приложения #18
noname_club, ой, а чтож в коде все так... Красиво

cu_translit - Это не ку, это кю. (c)

Добавлено через 2 минуты
Vorona, А я вот люблю категории. И если категории хорошо именовать, например NSData+Crypto, то сразу понятно что и как. А потом можно NSString+Crypto сделать, а внутри использовать NSData+Crypto. Вообще класс, имхо.
Yandex
Объявления
26.07.2013, 19:03     Безопасность платного приложения
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru