办公设备维修网
资讯中心 您所在的位置:网站首页 资讯中心 让离线程序也需要输入校验码(激活码)才可使用(python实现)

让离线程序也需要输入校验码(激活码)才可使用(python实现)

2024-06-16 20:52:52| 来源: 网络整理

我遇到个需求:需要给离线程序加一道锁,防门外汉的那种。因为离线程序遇到高手,肯定是会被破解的。像IntelliJ全家桶这样超大型软件,都无法防止用户的暴力破解。何况我这小打小闹的玩意。所以,目的就是防止一些普通的程序员也能轻易破解软件。

实现效果

假设已经开发了一个桌面应用“test.exe”(该软件不联网),那么每次安装程序的时候,都需要输入验证码(激活码)才能安装,该激活码需要向软件所有者索要。从而达到了防止程序被随意拷贝安装使用的目的。

那么验证码如何才能实现实时更新且由软件所有者提供呢?

实现方法

我想到的方法是根据时间,来生成一个验证码。为什么要根据时间呢?因为离线程序和软件所有者,所拥有的相同的元素,可能就是时间了。

当然验证码校验的方式肯定是:离线程序和软件所有者拥有一样的验证码生成算法,这样才能保证验证码能通过验证。 所以这种方案的缺陷便是:只要验证码生成算法被破解,那么防御就失效。而破解这个算法难度也不会很大,只要对程序代码进行分析,找到加密所在的代码,即可破解。毕竟离线程序的代码都在计算机本地,高手自然有手段对代码进行逆向,再分析。

不过程序员都知道,分析别人写的代码是一件很恶心的事,特别是拿到的还不是源码(没有注释,可能变量名也被混淆了),只是逆向出来的代码。可读性很差。所以破解离线程序的代价也是很大的。所以稍微加一点防御措施,也能让不少人望而却步。

好了,目的和意义交代完了,进入主题。

验证码生成算法

验证码有以下特点:

无规律有时效性

上面说到,我能想到的离线程序和软件所有者之间的共有要素只能想到“时间”。时间是随时在变化的。对时间加以处理,便可以得到无规律的验证码。

验证码生成的时间点

我们时间常用的精度是秒。如果我们每秒都生成一个验证码的话,那么验证码的量很大,且时效性太短,没有意义,所以我选择以分钟为单位来生成验证码。当然,也可以根据需要,以小时,天为单位生成验证码。

import timetimeStamp = int(time.time()) # 取时间戳,并转化为整数minTime = timeStamp - timeStamp % 60 # 取余60得到当前秒数,减去秒数即得到分钟级别的时间戳

python默认获取的时间戳是秒级,且后面带有小数点,所以这两行就是先取整,然后把秒去掉,保留分钟级别的时间戳。

验证码的时效性

通常我们收到验证码时,都会提示验证码的有效时间为10分钟。 我为了实现类似的效果(总之就是保证验证码是在一段时间内有效的),想到了一个蠢办法:

将当前时间的前后15分钟范围内的验证码都生成出来,与软件所有者提供的验证码比对,只要有一个比对成功,就认为验证码正确。

这样做的目的是因为不联网的电脑的时间经常不准,差个几分钟很正常,所以我取正负15分钟,在大多数情况下确保软件所有者提供的验证码包含在这个范围内。

理解了这个思路,那么就可以根据自己的实际情况调整验证码的有效期。

for j in range(-15, 15): minTimeRange = minTime + 60 * j # 加60秒即一分钟,每次加一分钟 保证验证码无规律

为了无规律,可以以时间戳为seed,生成随机数,这样基本也无规律,但是它有一个问题,它不能跨编程语言,也就是相同的seed,不能保证python和java生成的随机数相同。这就会为以后验证码校验制造困难。

你想想,软件所有者难道时时刻刻坐在电脑面前?索要验证码的人可不管你在不在电脑面前,他也不想等你回到电脑面前。这种时候,搞个app在手机上,用同样的算法实现,那么生成的验证码也能保证一致。安卓平台使用java开发的,桌面软件通常不用java,所以用随机函数不靠谱。

我就想到一个方法:

将前面获取的分钟级的时间戳转化为list,每个数字一个坑(这个时候注意最后一位数始终是0,所以实际处理时可以把尾数忽略掉)初始化result=0,再初始化seed=131073(为保证验证码的位数为6位数,所以取刚迈进6位数的二进制数“100000000000000001”,换成别的数也可以达到一样的效果,只是获取的验证码位数不固定而已)每次循环从list取一位数,将seed用位运算符“


【本文地址】 转载请注明 

最新文章

推荐文章

CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备16040606号-1