macOS 有试用期的应用验证策略问题请教

2020-02-24 18:19:09 +08:00
 FaiChou

一般收费并且有免费试用期的 APP 有两种验证策略:

  1. 应用安装时将安装日期或到期日期写到本地
  2. 使用唯一 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:

我在研究另一款试用软件时候(仅学习研究用),发现它使用的 id 并不是这个 UDID,而且卸载重装时候发现,这个 id 还是之前的 id。既然不是 UDID,那么它有可能将 UUID 保存到 keychain 里来持久化,但是去 keychain 里并没有找到。

所以好奇它是如何做到的,在联网验证时候,一般使用哪一种 id ?

以上的测试软件是 Sip, 使用 charles 抓包验证此 id 非 UDID:

我的电脑 Hardware UUID13C2951E-2B99-510A-BEF4-xxxxxxxxxx

2486 次点击
所在节点    macOS
14 条回复
Mitt
2020-02-24 18:39:01 +08:00
用系统序列号不好吗,那玩意也是唯一的
NeezerGu
2020-02-24 18:51:06 +08:00
看到你懂这么多,我就好奇请教一下。。。

第二步里,是不是我只需要想办法不断的修改我软件里的 udid,就能无限试用?
FaiChou
2020-02-24 19:03:40 +08:00
@Mitt #1 在 iOS 下获取不到序列号,macOS 上我不确定可不可以,但我的疑问是 Sip 这个软件的唯一 id 是怎么保持不变的?

@NeezerGu 理论上是的,但你首先你得确定软件用的是哪种 id,比如 Sip 这个软件它就不是你的系统 UDID。当然你也可以针对抓包的这个接口进行重放,修改返回信息来达到所谓的「无限试用」。
elderwand
2020-02-24 19:14:02 +08:00
@FaiChou
这里的 UDID 也是 UUID 的一种,只是叫法不一样,不算歧义

Sip 可能是用了 IDFA,你可以试试重置 IDFA 看看
macOS 可以用系统序列号吗?
https://gist.github.com/leogdion/77f6143ecf793e1ba381917d4b3b286c
Mitt
2020-02-24 19:45:59 +08:00
@FaiChou macos 可以用序列号,ios 苹果是不允许跟踪用户的,也就不允许你获取设备唯一码,以前看过别人绕过的方法,是在 keychain 里自己随机生成一串放进去,卸载也不会删除,变相跟踪,不知道是不是类似的方法,如果开了 iCloud 存储的话应该是有效的
FaiChou
2020-02-24 19:50:59 +08:00
@elderwand 谢谢纠正,我重置了电脑的 IDFA,重装 Sip,发现 id 没变。

@Mitt 在问题中我也提到过「将 UUID 保存到 keychain 里来持久化」,这种方法我做 iOS 时候用过,但是我在电脑 keychain 里找不到 Sip 相关的 item,大概也能排除这种方法。
Mitt
2020-02-24 19:54:06 +08:00
@FaiChou macOS 特别一点 其实卸载软件配置文件似乎不会删除,你可以找找是不是残留的文件里存了类似的 id 虽然可能是加密的
FaiChou
2020-02-24 19:56:19 +08:00
@Mitt #7 我用的是 AppCleaner,它会扫描软件相关所有内容,进行删除,暂且相信它。
Mitt
2020-02-24 20:06:38 +08:00
@FaiChou 如果不是 App Store 下载的软件就不要相信第三方 Cleaner 的准确度了,沙盒外的软件是可以在任何地方拉屎的,那保不齐它把配置文件塞哪里了,第三方清理软件并不能准确跟踪
FaiChou
2020-02-24 21:25:19 +08:00


在使用 "Hopper Disassembler v4" (第一次使用)查看 Sip 的反编译,能搜到关于 UUID 和 keychain 的相关代码,不过有一大部分是 AppCenter 的代码,但也能发现 Sip 也是用了 UUID 和 keychain。

我记得上午在 keychain 里找到过 Sip 相关但一个 item,被我删掉了,但是重装几次 Sip,keychain 里就再也找不到有关但证据了。

现在一头雾水。
FaiChou
2020-02-24 22:21:16 +08:00
@Mitt 这个软件的开发者回复我了,他用的就是序列号(kIOPlatformSerialNumberKey)。
aptx4689
2020-02-25 00:34:52 +08:00
软件开发者居然还会回复这种问题,太热心了
FaiChou
2020-02-25 10:08:05 +08:00
@aptx4689 #12 如果有人问我 app 的相关细节,我也会回复的,但那个作者在 10 分钟就回复我的邮件也太效率了。
ihwbunny
2020-02-26 13:28:29 +08:00
我想一种逻辑可以这样:

每次运行
. 判断证书, 如果有效, 就继续运行
. 如果没有有效的证书, 就获得本机 ID (不管什么硬件 ID)
. 上传到服务器, 服务器根据这个 ID, 判断:
1. 没有记录, 生成一个有时效的证书, 比如试用 30 天, 发给客户端, 并保留硬件 ID 和证书等数据
2. 有记录, 而且证书没失效, 发给客户端, 客户端可以继续试用
3. 有记录, 而且失效, 告诉客户端购买
. 客户端把证书保留在 keychain 中
. 如果本地证书已经失效, 告诉客户端购买

这个的好处是, 无论有没有网络都可以, 而且时间和证书发放都掌握在服务器端.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/647170

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX