问题已解决非常感谢
到期时间戳:5703d6604715cbb196f74fb19211dd34|17938483222592000
现行时间戳:1793849410
为什么系统判定上面的时间戳小于下面的,提示到期了呢?
您这个上面的时间戳有17位,这个是微秒时间戳,已经远超整数型的可比较范围了,整数型最大只能比较十位,而且生成到期时间戳时,应该生成10位时间戳才对,如果超过10位时间戳,那应该判断是否永久注册或者使用长整数或者大数比较了。
到期时间戳:5703d6604715cbb196f74fb19211dd34|17938483222592000
现行时间戳:1793849410
为什么系统判定上面的时间戳小于下面的,提示到期了呢?
我觉的方案一就够了,和谁对接,留个联系方式。
IDE启动页面(欢迎页面)右侧有类库、软件定制相关联系方式,加好友联系即可。
我觉的方案一就够了,和谁对接,留个联系方式。
非常感谢,再就是有没有视频加密的库,封一个好用点的多少米?
单纯对视频加密并不难,主要比较复杂的是:要想更安全的防止逆向破解,整个解密过程要流式解密,或放在SO库里面,不能直接在 Java 层。
目前主流的对视频保护有两种方案。
方案一:
如果视频文件较大,单个文件加密后大于200MB及以上,则一般使用自定义播放器,自定义封装 ExoPlayer 的 Seekable 流式数据解密,难度尚可,Java层解密,安全性一般,视频无法快进或后退,因为解密数据块只能按照顺序解密。封装价大约300元左右。
方案二:
如果视频体积不大,对播放性能要求不高、将全部解密操作放在SO库中实现,在应用私有目录创建临时文件、在SO层解密文件后、写入临时文件,播放完成后立即删除;播放期间禁止外部访问。难度较大,需要编写SO库文件,安全性较高,视频可正常快进或后退,封装价格大约800元。
另外更安全的方案:
即方案一+方案二组合,在SO库层流式解密,然后用 ExoPlayer 自定义 DataSource 的 IO 流,让解密发生在播放器读取链路里,而不先解密输出一个完整的明文 MP4 文件,因为虽然方案二在私有目录写出了临时文件,但是如果破解者通过 ADB、内存 dump、动态调试工具仍然有可能获取到完整视频文件。
因此最佳建议即在SO库层流式解密,解密后再通过自定义数据结构传给播放器播放,这样就算破解者在调试器中抓到了视频流数据,但格式是乱码的,只有自定义的播发器源认识这串数据。但前提是:流式解密不支持视频快进后退。
这种方案可靠性、安全性更高,但是实现难度较大,封装价格大约1000元左右。
非常感谢,再就是有没有视频加密的库,封一个好用点的多少米?
我就是遇到了这个问题,保存设置那一块。将软件删除以后,重新安装又变可成30天了。
不会的,卸载时会将注册信息一并删除,重新安装后,要重新注册才能用,但注册码中的到期时间戳还是固定的到期时间,只要您不给对方新注册码,让对方用旧的注册码即可。
我就是遇到了这个问题,保存设置那一块。将软件删除以后,重新安装又变可成30天了。
如果我想记录软件使用时间,设置软件到期时间,用哪个方案合适?
如果是单机版APP,可参考视频课程:单机APP实现机器码与注册码激活
http://bbs.vcnstudio.com/?c=course&a=player&id=3
实现流程:
1.在您的APP里面要增加一个获取用户设备机器码的功能。
2.再单独写一个APP,输入用户的机器码,然后输入可用时间,例如30天、用机器码加时间值生成一个注册码。
3.将注册码发送给用户,用户复制注册码到APP里面激活。
代码演示:
' 客户端APP获取手机设备信息,并生成机器码
函数 获取设备机器码() 为 文本型
返回 取文本MD5(取设备信息() + 取设备ID() + 取设备厂商() + 取设备型号())
结束 函数管理端(负责生成注册码的APP):
' 使用用户端APP取出的设备机器码、在管理端APP生成注册码,时长单位:天
' 假设:30 天 = 30 × 24 × 60 × 60 = 2,592,000 秒
' 到期时间戳 = 当前10位时间戳 + 2,592,000
函数 生成注册码(机器码 为 文本型,时长 为 整数型) 为 文本型
变量 到期时间戳 = 取现行时间戳(2) + (时长 * 24 * 60 * 60)
返回 RC4加密文本(机器码 + "|" + 到期时间戳,"qwer1234")
结束 函数客户端(用户端APP)注册激活APP:
' 在客户端注册APP,解密注册码并保存配置,验证到期时间
函数 客户端注册(注册码 为 文本型)
变量 解密后内容 = RC4解密文本(注册码,"qwer1234")
' 分隔“|”取出到期时间戳,检测机器码是否已过期
变量 解密后文本数组 = 分割文本(解密后内容,"|",假)
' 取出到期时间戳
变量 到期时间戳 = 到整数(解密后文本数组[1])
' 判断时间戳是否到期,如果到期时间戳比今天小,也就是相当于在昨天就已经过期了
如果(到期时间戳 < 到整数(取现行时间戳(2)))
弹出提示("当前注册码已经在今天之前过期了!")
返回
结束 如果
' 未过期,则保存配置,注意:这里不能直接写出到储存卡(公共目录)
' 卸载APP后,或手机恢复出厂设置,必须重新注册,防止逆向抓包解密
保存设置("license",到文本(到期时间戳))
结束 函数客户端(用户端APP)检测是否已经注册:
函数 客户端检测是否已注册()
变量 到期时间戳 = 读取设置("license")
如果(为空(到期时间戳))
弹出提示("你还未注册APP!")
返回
结束 如果
' 不为空则检测是否已经到期
如果(到整数(到期时间戳) < 到整数(取现行时间戳(2)))
弹出提示("注册时间已到期!")
返回
结束 如果
' 正常注册、未到期、放行...
结束 函数 如果我想记录软件使用时间,设置软件到期时间,用哪个方案合适?
首先,由于安全和隐私原因,安卓系统针对开发者层面并没有提供永久配置文件的功能。
默认应用配置在卸载APP后,必须随APP一并删除。
要想实现卸载APP后,配置文件仍然存在,一般主流方式是自定义实现配置文件并将其保存到外部储存(公共目录),即通过手机文件管理可以看到的储存位置(储存卡空间),注意该方式必须在入口文件中启用储存卡读写权限。
代码示例:
函数 写永久配置项(配置项名称 为 文本型,值 为 文本型)
' 自定义配置文件格式,使用 json 或者 txt 都可以
' 这里使用 json 按照键值对储存
变量 配置文件 = 取储存卡路径() + "/permanent.json"
如果(文件是否存在(配置文件) == 假)
写出文本文件(配置文件,"{}","UTF-8")
结束 如果
' 读取文件并解析
变量 json内容 = 读取文本文件(配置文件,"UTF-8")
变量 json对象 = 创建 JSON对象()
如果(json对象.解析(json内容) == 假)
返回
结束 如果
' 追加一个配置项和配置的值
json对象.置文本(配置项名称,值)
' 保存写出文件
写出文本文件(配置文件,json对象.到文本(),"UTF-8")
结束 函数
函数 读永久配置项(配置项名称 为 文本型) 为 文本型
变量 配置文件 = 取储存卡路径() + "/permanent.json"
如果(文件是否存在(配置文件) == 假)
返回 ""
结束 如果
' 读取文件并解析
变量 json内容 = 读取文本文件(配置文件,"UTF-8")
变量 json对象 = 创建 JSON对象()
如果(json对象.解析(json内容) == 假)
返回 ""
结束 如果
' 取出指定配置项的名称
如果(json对象.取字段是否为空(配置项名称) == 真)
返回 ""
否则
返回 json对象.取文本(配置项名称)
结束 如果
结束 函数
一般这种方式可以将其封装成一个静态类,即类似公用模块,在项目中使用:
定义 永久配置模块 为 类
' 定义配置文件路径
变量 静态 配置文件路径 = 取储存卡路径() + "/permanent.json"
' 构造函数(函数名必须与类名相同)
函数 静态 初始化()
如果(文件是否存在(配置文件路径) == 假)
写出文本文件(配置文件路径,"{}","UTF-8")
结束 如果
结束 函数
' 写永久配置项方法
函数 静态 写永久配置项(配置项名称 为 文本型,值 为 文本型)
' 读取文件并解析
变量 json内容 = 读取文本文件(配置文件路径,"UTF-8")
变量 json对象 = 创建 JSON对象()
如果(json对象.解析(json内容) == 假)
返回
结束 如果
' 追加一个配置项和配置的值
json对象.置文本(配置项名称,值)
' 保存写出文件
写出文本文件(配置文件路径,json对象.到文本(),"UTF-8")
结束 函数
' 读永久配置项方法
函数 静态 读永久配置项(配置项名称 为 文本型) 为 文本型
如果(文件是否存在(配置文件路径) == 假)
返回 ""
结束 如果
' 读取文件并解析
变量 json内容 = 读取文本文件(配置文件路径,"UTF-8")
变量 json对象 = 创建 JSON对象()
如果(json对象.解析(json内容) == 假)
返回 ""
结束 如果
' 取出指定配置项的名称
如果(json对象.取字段是否为空(配置项名称) == 真)
返回 ""
否则
返回 json对象.取文本(配置项名称)
结束 如果
结束 函数
结束 定义
在窗口中使用:
事件 窗口创建完毕()
' 必须先在主窗口或第一次启动的窗口中初始化
永久配置模块.初始化()
结束 事件
事件 按钮_1.被单击(来源对象 为 视图)
' 保存配置
永久配置模块.写永久配置项("用户名","张三")
永久配置模块.写永久配置项("密码","123456")
结束 事件
事件 按钮_2.被单击(来源对象 为 视图)
变量 用户名 为 文本型 = 永久配置模块.读永久配置项("用户名")
变量 密码 为 文本型 = 永久配置模块.读永久配置项("密码")
调试输出("用户名: " + 用户名)
调试输出("密码: " + 密码)
结束 事件