一般收费并且有免费试用期的 APP 有两种验证策略:
- 应用安装时将安装日期或到期日期写到本地
- 使用唯一 id 来联网验证
本地验证
这种方法比较简陋,可以用脚本等方法篡改使用期限。
联网验证
这种方法应该可以躲避一些脚本,但获取唯一 id 是个难题,这也是我提出本问题的原因。
用以下代码可以获取一个系统的 id:
- (NSString *)getSystemID {
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,IOServiceMatching("IOPlatformExpertDevice"));
if (!platformExpert)
return nil;
CFTypeRef serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert,CFSTR(kIOPlatformUUIDKey),kCFAllocatorDefault, 0);
if (!serialNumberAsCFString)
return nil;
IOObjectRelease(platformExpert);
return (__bridge NSString *)(serialNumberAsCFString);;
}
获取的 id 和电脑打开系统报告看到的 Hardware UUID 是一样的,我认为这里的 Hardware UUID 字段有歧义,按我的理解应该是 UDID.
关于 UUID 和 UDID:
- UUID 是电脑给应用配置的唯一 id,当 app 卸载重装,这个 id 会变
- UDID 是电脑唯一 id,一般情况禁止使用,使用它不能上架市场
我在研究另一款试用软件时候(仅学习研究用),发现它使用的 id 并不是这个 UDID,而且卸载重装时候发现,这个 id 还是之前的 id。既然不是 UDID,那么它有可能将 UUID 保存到 keychain 里来持久化,但是去 keychain 里并没有找到。
所以好奇它是如何做到的,在联网验证时候,一般使用哪一种 id ?
以上的测试软件是 Sip, 使用 charles 抓包验证此 id 非 UDID:

我的电脑 Hardware UUID 是 13C2951E-2B99-510A-BEF4-xxxxxxxxxx

