Андриан Буданцов_Секретные способы идентификации...
DESCRIPTION
Секретные способы идентификации пользователей iOS Андриан Буданцов Co-founder and CTO at iOS software company Readdle Как правильно посчитать количество уникальных пользователей, надежно отличать конкретный девайс и бороться с пиратством. Что знают про iOS девайс рекламные сети. История вопроса и последние нововведения.TRANSCRIPT
Секретные способыидентификациипользователей iOS
Андриан Буданцов
Зачем?1. Отличать → считать разныеколичествопрофайлытаргетинг...
2. Хранение данныхнастройкипривязка девайса к аккаунту...
Статистика
Статистика
Идентификация
Идентификатор
разные значения на разных устройствах
одинаков для всех приложений в которыхсобирается статистика
не меняется для одного пользователя
Device Id: uniqueIdentifier
[[UIDevice currentDevice] uniqueIdentifier]
UDID
160-бит число вроде16a830fd2789754cb2b299b067b845f8579d5eb4
слишком привязан к hardware
Device Id: uniqueIdentifier
deprecated в iOS 5 (2011)
начали реджектить весной 2012
приложения в AppStore работали до iOS 6
Device Id: uniqueIdentifierвсе еще используется
для development и adhoc сборок
в Mobile Device Management
Свой идентификатор
UUID — случайное 128-бит число
сохранить в настройки
не выдерживает переустановку
работает только с одним приложением
выдерживает backup-restore на другойдевайс
Свой идентификаторKeyChain
appUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];[SSKeychain setPassword:appUUID forService:appName account:kDeviceId];
выдерживает переустановку
доступен для нескольких приложенийодного разработчика в одной access group
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
Device Id: MAC address if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { printf("Error: sysctl, take 1\n"); return NULL; }
if ((buf = malloc(len)) == NULL) { printf("Could not allocate memory. error!\n"); return NULL; }
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { printf("Error: sysctl, take 2"); free(buf); return NULL; }
ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X" *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr free(buf);
Device Id: MAC address
в Китае продавались iPhone 3GS накоторых был отключен Wi-Fi
всегда возвращает 02:00:00:00:00:00 на iOS 7+
Device Id: UIPasteboard
именованный буфер обмена
доступен всем приложениям по имени начтение и запись
persistent
Device Id: UIPasteboard
Device Id: UIPasteboard
iOS 7: pasteboardWithName:create:работает только для приложений в однойapplication group
кратковременная передача данных черезgeneral pasteboard
Официальные API
iOS 6+
identifierForVendor
advertisingIdentifier
identifierForVendorOfficial iOS 6+ API
[[UIDevice currentDevice] identifierForVendor]
Одинаковый для одного AppStore-разработчика
AdHoc / Enterprise: одинаковый* id дляпохожих com.bundle (*iOS 6/7)
Разный для adhoc/app store сборок
может поменяться
identifierForVendorможет поменятся
на nil (повторить вызов)
при переустановке последнего приложенияразработчика
при адпейте iOS (?)
в других случаях
advertisingIdentifier[[ASIdentifierManager sharedManager] advertisingIdentifier]
в iOS 6 бетах был
[[UIDevice currentDevice] identifierForAdvertising]
из AdSupport.framework
advertisingTrackingEnabled
нужна причина использования
может поменяться
Отступление: хранение UUID
Значение 128 бит
Каноническое hex-представлениеhex 8-4-4-4-12, например:B704C214-EE76-47DB-8CA2-97A9FAD184D7
base64url (Base64 -_ вместо +/ )sA9kDM_tRlW0HmywjZCj8Q
экономия 38%
idfv+keychain
сохраняет identifierForVendor в Keychainдля приложения
см. свой идентификатор
ничем не лучше обычного UUID
UUID + iCloud
случайный UUID в iCloud
создается при первом запуске приложения
можно шарить между приложениями
считает уникальных iCloud пользователей
iTunes User ID
FairPlay DRM, US Patent US7936873
iTunes User ID
чем отличаются приложения купленныеразными пользователями?
%product%.app/SC_Info/%product%.sinf/SC_Info/%product%.supp
iTunes User ID
iTunes User ID
количество инсталляций у одногопользователя
список девайсов у пользователей
было: сопоставить iTunes комментарии(содержал dsId) и запуск приложения
iTunes User ID
все еще доступен
но iOS7+ не дает прочитать файл
StoreKit Receipt[[NSBundle mainBundle] appStoreReceiptURL]
единственный метод для которого неработает respondsToSelector:
%sandbox%/StoreKit/receipt
“Receipt Validation Programming Guide”
PKCS#7 контейнер со значениями в ASN.1
StoreKit Receipt
StoreKit + verifyReceipt
HTTP POST вhttps://buy.itunes.apple.com/verifyReceipt
StoreKitOriginal Purchase Date
разрешение до секундыподходит большинству платныхприложениям
позволяет узнать по какой цене купиливаше приложение
борьба с AppStore пиратством
Original Purchase DateНемного уточнений
[[NSLocale currentLocale] localeIdentifier]
[[NSTimeZone localTimeZone] secondsFromGMT]
sysctlbyname("hw.machine", machine, &size, NULL, 0);
[[NSFileManager defaultManager] attributesOfFileSystemForPath:p error:&e]
Core Telephonylet carrier = CTTelephonyNetworkInfo().subscriberCellularProviderNSLog("country %@ network %@" , carrier.mobileCountryCode, carrier.mobileNetworkCode);
см. wikipedia:Mobile country code
у Украины действительно MCC = 255
carrierName = Carrier для неизвестныхоператоров
Кратковременнаяидентификация
Access Point BSSID
CFDictionaryRef CNCopyCurrentNetworkInfo(CFStringRef interfaceName)
Boot Time
int mib[2] = {CTL_KERN, KERN_BOOTTIME}; size_t size = sizeof(boottime); time_t now; time_t uptime = -1; (void)time(&now); if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec !=
Идентификация в Safari
Нужно для конверсий из браузера
REMOTE_ADDR
iOS версия
тип девайсаiPhone / iPad / iPod / retina
короткое время
Пиратские копии
AdHoc / Enterprise InHouse сборкинет Receipt
App Store пиратствоOriginal Purchase Date
Jailbreak-пиратствопроверка receipt / binary hash
Часто собираемаяинформация
Свой идентификатор
Advertiser Identifier
флаг "Pirated"
флаг "jailbroken"
имя оператора
Часто собираемаяинформация (2)
модель девайса
подключение к сети
разрешение экрана
громкость звука
свободное место
Идентификация
Свой идентификатор в Keychain
Advertiser Identifier для рекламы
Receipt для дополнительной информации
Вопросы
?
Спасибо за внимание@andrianbdn • [email protected]