如何设计一个尽量防止破解的系统激活码

18 小时 18 分钟前
 chobits336

系统部署到客户的服务器,全部服务用 docker 启动,如何设计一个激活码机制让这个系统到指定时间不能使用

现在的设计是:

  1. 生成 rsa 公私钥,使用私钥加密 license ,部署时配置 license 文件
  2. 公钥放在系统中,使用公钥解密 license 校验其合法性
  3. license 里有系统 id 、签发人、过期时间属性

部署是离线环境,防止通过修改系统时间来破解授权,就想到了用系统运行时间来校验;将运行时间加密存在文件里,但如果这个时间文件被删除或被克隆,记录的运行时间就会被重置了,请问各位大佬怎么解决这个问题

3535 次点击
所在节点    程序员
43 条回复
la2la
15 小时 0 分钟前
咨询一下律师,签个合同,软件到期后不续费接着用就告他
wfhtqp
14 小时 59 分钟前
@chobits336 除非业务数据不存数据库,他还能把业务数据都重置掉?
nealHuang
14 小时 59 分钟前
你的需求跟我的一模一样。但我完全不担心时间回溯,你想想,数据库中很多纪录都是带时间的,如果他们回溯了时间,那么这一批未来数据就没有意义了,或者整个系统的业务数据都会发生错乱了。如果恢复了快照,那么也没法保留数据了,如果系统对他们很重要,那么业务数据是很关键的,如果系统不重要,那么也不会去回溯快照
chobits336
14 小时 58 分钟前
@msg7086 这个时间戳是系统时间吗,如果恢复快照前是 2024-11-01 ,回滚快照后再把系统时间改为 2024-11-01 就可以通过校验;如果这个时间是系统运行时间(加密不能被篡改)倒是可以校验一致性,但数据里掺杂时间戳感觉太麻烦了,还是说每个业务表加个字段,但这个字段的值可以篡改呀
chobits336
14 小时 54 分钟前
@nealHuang 可以先把数据 dump 出来,恢复快照后再 load 进去,这样系统也可以用,数据也还在
InDom
14 小时 33 分钟前
楼上一堆说把时间嵌入数据中的,楼主是一个也没听懂啊...

假设授权时间为 2024-01-01 ~ 2024-12-31 的 365 天,并且假设系统第一次使用的时候时间是准确的。

并且假设每天客户都会添加一条新数据,并且每条数据都带有当前具体时间。

那么,如果你需要验证当前使用是否到期,只需要从数据库中取出时间最早和最晚的时间,取时间差,是不是超过 365 天了,超过就不能用。

你需要验证的时间信息始终是跟着数据的时间走的,客户只要需要保留数据,就没法作弊。

如果你担心数据导出来修改时间,你可以对导出数据加密,还可以每条数据都把当前数据 与上条数据的 hash 作为自己的 hash 来防篡改。
Esec
14 小时 21 分钟前
日志,存储,系统自身文件,甚至宿主文件系统和硬件都是可以埋雷的地方,就是容易报毒,毕竟做的事情本质上差不多
mylovesaber
14 小时 12 分钟前
楼主项目什么语言写的?我这隔壁组一个 java 老哥解决你这种问题的思路是:
java 是能够轻松反编译的语言(编译出来的文件直接拖进 ide 就能看到源码的程度)
rust 主打一个安全,很难被反编译,

用 rust 写一个启动器,把 key 写在启动器中,魔改 springboot 框架的启动器,将其功能改成 rust 启动器来启动,时间信息加密分散到数据库中,让 rust 去调数据库拿数据,验证通过才能唤醒 sb 启动器来启动项目,而单独启动 java 项目是无法工作的。至于时间怎么防回滚,你可以自行思考下,写文件是不能接受的行为,必须写数据库
chobits336
14 小时 7 分钟前
@InDom 感谢,这样的确可以解决办法,license 的过期时间改为 xxx 天而不是具体的时间,每个数据表加一个 hash 字段,hash 上一条数据的 id ,就不会被外部篡改了,但数据表的修改和删除就会变得很麻烦
msg7086
13 小时 59 分钟前
@InDom 对,差不多就是你说的意思。
然后你说的最后一句话其实就是区块链的概念。
不过这种做法也不简单,需要专门做一个抽象层去处理,或者在系统开始设计的时候就考虑进去,后加就麻烦。
zengxs
13 小时 47 分钟前
禁止他重启你的系统就行了,每次开机要你们的人到现场操作,并且收开机费

上次我朋友去医院做飞秒,医生给他说做飞秒的机器就是这样收费的,每开一次机要收 1w
医院只能把所有病人集中到每周的某一天做手术,这样一周只开一次机就行
iorilu
13 小时 29 分钟前
搞这么麻烦干啥

我想到个方法

系统启动时候需要输入口令, 这口令和当前日期有关系, 每次启动时候需要对方找你, 你根据日期生成口令
给他, 这样就不存在启动的时候修改日期

这样就解决了客户单独启动的问题, 反正服务器也不可能经常重启把

至于运行时候到期判断, 这就记录数据时间阿 , 每天记录第一笔数据之前查找下系统内是否有更新的数据, 如果有必然是当前时间被改到了过去
InDom
13 小时 13 分钟前
楼主最后附言的方案,是打算自己单独建一个表么?

如果我 docker exec mysql ,然后删除、清空你的这个表会怎么样呢?

一定要把时间融入到他们的业务中,数据和使用二选一。

@iorilu #32 ,启动时提供授权是个好主意,相当于间接同步时间了。
chobits336
13 小时 10 分钟前
@InDom 清空 license_record 表就启动不了系统,第一条记录为 license 凭证,这个凭证也不能被复用
iorilu
13 小时 4 分钟前
@InDom 我个人觉得有这步就够了, 其实也是表明一个态度, 说明很重视版权, 想用就得给钱, 别想白嫖

其他也没必要, 你软件要真那么牛, 值得费大力气折腾绕过, 那应该早赚大钱了
maladaxia
12 小时 49 分钟前
@rekulas 有 gps 访问权限也可以, gps 有时间
maladaxia
12 小时 42 分钟前
我还有个办法,
1. 运行你的程序获取环境信息
2. 客户把环境信息发给你, 你来计算激活码
3. 客户用激活码激活

环境信息里应该包含时间和硬盘运行时间等信息
从而保证这个激活码只能一次性使用
youyouzi
11 小时 8 分钟前
网银的 U 盾啊。这不是很成熟的加密方式了嘛?
ladypxy
10 小时 24 分钟前
最简单的,参考 2FA 原理,注册就绑定一个 2FA 的 token ,到期从服务器删除即可
barfi1316
7 小时 55 分钟前
@chobits336 如果 license_record 表清理只保留第一条,同时修改系统时间,是不是 license 就重新计算?

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

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

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

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

© 2021 V2EX