本文深入探讨易语言网络验证系统的开发原理、加密算法、通信协议和防破解技术,通过完整的实战案例展示如何构建安全可靠的软件授权管理系统。
![图片[1]-易语言网络验证系统开发实战:安全加密与防破解技术](https://blogimg.vcvcc.cc/2025/11/20251126120346144-1024x768.png?imageView2/0/format/webp/q/75)
一、网络验证系统架构设计
1.1 系统架构与核心组件
' 易语言网络验证系统核心模块
' 包含客户端验证、服务器通信、数据加密等核心功能
.版本 2
.支持库 iext
.支持库 sock
.支持库 dp1
.程序集 网络验证系统
.程序集变量 服务器地址, 文本型
.程序集变量 通信密钥, 文本型
.程序集变量 客户端信息, 客户端信息类型
.程序集变量 加密对象, 加解密对象
.数据类型 客户端信息类型
.成员 机器码, 文本型
.成员 软件版本, 文本型
.成员 登录时间, 日期时间型
.成员 用户等级, 整数型
.成员 到期时间, 日期时间型
.数据类型 服务器响应类型
.成员 状态码, 整数型
.成员 消息内容, 文本型
.成员 数据内容, 文本型
.成员 时间戳, 文本型
.成员 签名, 文本型
二、客户端验证模块实现
2.1 核心验证类实现
.版本 2
.支持库 spec
.支持库 sock
.程序集 客户端验证类
.程序集变量 服务器配置, 服务器配置类型
.程序集变量 本地缓存, 本地缓存类型
.程序集变量 网络通信, 网络通信类
.数据类型 服务器配置类型
.成员 主服务器地址, 文本型
.成员 备用服务器地址, 文本型
.成员 通信端口, 整数型
.成员 超时时间, 整数型
.成员 加密密钥, 文本型
.数据类型 本地缓存类型
.成员 最后验证时间, 日期时间型
.成员 验证令牌, 文本型
.成员 缓存有效期, 整数型
.成员 用户信息, 文本型
.子程序 _初始化, , , 当基于本类的对象被创建后,此方法会被自动调用
服务器配置.主服务器地址 = "api.verify.example.com"
服务器配置.备用服务器地址 = "backup.verify.example.com"
服务器配置.通信端口 = 8080
服务器配置.超时时间 = 10000
服务器配置.加密密钥 = "B2E3A7F8C9D1E5F6A8B3C4D5E6F7A8B9"
本地缓存.缓存有效期 = 3600 ' 1小时
.子程序 _销毁, , , 当基于本类的对象被销毁前,此方法会被自动调用
' 清理资源
' 主验证函数
.子程序 验证登录, 逻辑型, 公开, 验证用户登录状态
.参数 用户名, 文本型
.参数 密码, 文本型
.参数 软件ID, 文本型
.局部变量 请求数据, 文本型
.局部变量 响应数据, 文本型
.局部变量 解密数据, 文本型
.局部变量 验证结果, 逻辑型
' 1. 构建请求数据
请求数据 = 构建登录请求(用户名, 密码, 软件ID)
' 2. 发送验证请求
响应数据 = 网络通信.发送请求(服务器配置.主服务器地址, 请求数据)
.如果真 (响应数据 = "")
' 尝试备用服务器
响应数据 = 网络通信.发送请求(服务器配置.备用服务器地址, 请求数据)
.如果真结束
.如果真 (响应数据 = "")
信息框 (“网络连接失败,请检查网络设置”, 0, , )
返回 (假)
.如果真结束
' 3. 解密响应数据
解密数据 = 加密解密类.AES解密(响应数据, 服务器配置.加密密钥)
' 4. 解析响应
验证结果 = 解析登录响应(解密数据)
.如果 (验证结果)
' 5. 更新本地缓存
更新本地缓存(解密数据)
' 6. 记录登录日志
记录安全日志(“用户登录成功”, 用户名)
.否则
' 记录失败日志
记录安全日志(“用户登录失败”, 用户名)
.如果结束
返回 (验证结果)
.子程序 构建登录请求, 文本型, 私有
.参数 用户名, 文本型
.参数 密码, 文本型
.参数 软件ID, 文本型
.局部变量 请求JSON, 文本型
.局部变量 时间戳, 文本型
.局部变量 随机数, 文本型
.局部变量 签名, 文本型
时间戳 = 时间_取现行时间戳()
随机数 = 文本_取随机字符(16)
请求JSON = “{” + #引号 + “action” + #引号 + “:” + #引号 + “login” + #引号 + “,”
请求JSON = 请求JSON + #引号 + “username” + #引号 + “:” + #引号 + 用户名 + #引号 + “,”
请求JSON = 请求JSON + #引号 + “password” + #引号 + “:” + #引号 + 取数据摘要 (到字节集 (密码)) + #引号 + “,”
请求JSON = 请求JSON + #引号 + “software_id” + #引号 + “:” + #引号 + 软件ID + #引号 + “,”
请求JSON = 请求JSON + #引号 + “machine_code” + #引号 + “:” + #引号 + 取机器码() + #引号 + “,”
请求JSON = 请求JSON + #引号 + “timestamp” + #引号 + “:” + #引号 + 时间戳 + #引号 + “,”
请求JSON = 请求JSON + #引号 + “nonce” + #引号 + “:” + #引号 + 随机数 + #引号 + “}”
' 生成签名
签名 = 生成请求签名(请求JSON, 时间戳, 随机数)
请求JSON = 加密解密类.AES加密(请求JSON, 服务器配置.加密密钥)
返回 (请求JSON)
.子程序 解析登录响应, 逻辑型, 私有
.参数 响应数据, 文本型
.局部变量 JSON解析, 类_json
.局部变量 状态码, 整数型
.局部变量 消息内容, 文本型
.局部变量 数据内容, 文本型
.局部变量 签名验证, 逻辑型
.如果真 (JSON解析.解析 (响应数据) = 假)
返回 (假)
.如果真结束
状态码 = JSON解析.取整数 (“code”)
消息内容 = JSON解析.取文本 (“message”)
数据内容 = JSON解析.取文本 (“data”)
' 验证签名
签名验证 = 验证响应签名(响应数据)
.如果真 (签名验证 = 假)
返回 (假)
.如果真结束
.判断开始 (状态码 = 200)
' 登录成功
返回 (真)
.判断 (状态码 = 401)
信息框 (“用户名或密码错误”, 0, , )
返回 (假)
.判断 (状态码 = 402)
信息框 (“账户已过期”, 0, , )
返回 (假)
.判断 (状态码 = 403)
信息框 (“账户被禁用”, 0, , )
返回 (假)
.默认
信息框 (“验证失败:” + 消息内容, 0, , )
返回 (假)
.判断结束
.子程序 取机器码, 文本型, 公开, 获取客户端机器唯一标识
.局部变量 CPU序列号, 文本型
.局部变量 硬盘序列号, 文本型
.局部变量 网卡MAC, 文本型
.局部变量 原始机器码, 文本型
.局部变量 最终机器码, 文本型
' 获取硬件信息
CPU序列号 = 系统信息类.取CPU序列号()
硬盘序列号 = 系统信息类.取硬盘序列号()
网卡MAC = 系统信息类.取MAC地址()
' 组合生成机器码
原始机器码 = CPU序列号 + 硬盘序列号 + 网卡MAC
最终机器码 = 取数据摘要 (到字节集 (原始机器码))
返回 (最终机器码)
2.2 加密解密模块
.版本 2
.支持库 dp1
.程序集 加密解密类
.子程序 AES加密, 文本型, 公开
.参数 明文, 文本型
.参数 密钥, 文本型
.局部变量 加密结果, 文本型
.局部变量 加密对象, 加解密对象
加密对象.算法类型 = #对称算法_AES_256_ECB
加密对象.密码 = 密钥
加密结果 = 加密对象.加密 (明文, #编码方式_Base64)
返回 (加密结果)
.子程序 AES解密, 文本型, 公开
.参数 密文, 文本型
.参数 密钥, 文本型
.局部变量 解密结果, 文本型
.局部变量 解密对象, 加解密对象
解密对象.算法类型 = #对称算法_AES_256_ECB
解密对象.密码 = 密钥
解密结果 = 解密对象.解密 (密文, #编码方式_Base64)
返回 (解密结果)
.子程序 RSA加密, 文本型, 公开
.参数 明文, 文本型
.参数 公钥, 文本型
.局部变量 加密结果, 文本型
.局部变量 RSA对象, RSA加解密对象
RSA对象.载入公钥 (公钥)
加密结果 = RSA对象.公钥加密 (明文, #RSA填充方式_PKCS1)
返回 (加密结果)
.子程序 生成请求签名, 文本型, 公开
.参数 请求数据, 文本型
.参数 时间戳, 文本型
.参数 随机数, 文本型
.局部变量 签名字符串, 文本型
.局部变量 签名结果, 文本型
' 签名规则: data + timestamp + nonce + secret_key
签名字符串 = 请求数据 + 时间戳 + 随机数 + "SECRET_KEY_123456"
签名结果 = 取数据摘要 (到字节集 (签名字符串))
返回 (签名结果)
.子程序 验证响应签名, 逻辑型, 公开
.参数 响应数据, 文本型
.局部变量 JSON解析, 类_json
.局部变量 原始签名, 文本型
.局部变量 计算签名, 文本型
.局部变量 数据内容, 文本型
.局部变量 时间戳, 文本型
.如果真 (JSON解析.解析 (响应数据) = 假)
返回 (假)
.如果真结束
原始签名 = JSON解析.取文本 (“signature”)
数据内容 = JSON解析.取文本 (“data”)
时间戳 = JSON解析.取文本 (“timestamp”)
' 计算签名
计算签名 = 取数据摘要 (到字节集 (数据内容 + 时间戳 + "SECRET_KEY_123456"))
返回 (计算签名 = 原始签名)
三、服务器通信模块
3.1 网络通信核心类
.版本 2
.支持库 sock
.程序集 网络通信类
.程序集变量 客户端, 客户端
.程序集变量 超时时间, 整数型
.子程序 _初始化, , ,
超时时间 = 10000
客户端.自动重连 = 真
.子程序 发送请求, 文本型, 公开
.参数 服务器地址, 文本型
.参数 请求数据, 文本型
.局部变量 响应数据, 文本型
.局部变量 开始时间, 整数型
.局部变量 当前时间, 整数型
.如果真 (客户端.连接 (服务器地址, 8080) = 假)
返回 (“”)
.如果真结束
' 发送请求数据
客户端.发送数据 (请求数据)
' 等待响应(带超时)
开始时间 = 取启动时间 ()
.循环判断首 ()
程序_延时 (100)
当前时间 = 取启动时间 ()
.如果真 (当前时间 - 开始时间 > 超时时间)
客户端.断开连接 ()
返回 (“”)
.如果真结束
响应数据 = 客户端.取回数据 ()
.循环判断尾 (响应数据 = “”)
客户端.断开连接 ()
返回 (响应数据)
.子程序 心跳检测, 逻辑型, 公开
.参数 服务器地址, 文本型
.局部变量 心跳请求, 文本型
.局部变量 心跳响应, 文本型
心跳请求 = 构建心跳请求()
心跳响应 = 发送请求(服务器地址, 心跳请求)
.如果真 (心跳响应 = "")
返回 (假)
.如果真结束
返回 (解析心跳响应(心跳响应))
.子程序 构建心跳请求, 文本型, 私有
.局部变量 请求JSON, 文本型
.局部变量 时间戳, 文本型
时间戳 = 时间_取现行时间戳()
请求JSON = “{” + #引号 + “action” + #引号 + “:” + #引号 + “heartbeat” + #引号 + “,”
请求JSON = 请求JSON + #引号 + “token” + #引号 + “:” + #引号 + 本地缓存.验证令牌 + #引号 + “,”
请求JSON = 请求JSON + #引号 + “timestamp” + #引号 + “:” + #引号 + 时间戳 + #引号 + “}”
返回 (加密解密类.AES加密(请求JSON, 服务器配置.加密密钥))
四、防破解与安全保护
4.1 反调试与代码保护
.版本 2
.支持库 krnln
.支持库 eAPI
.程序集 安全防护类
.子程序 检测调试器, 逻辑型, 公开, 检测是否被调试器附加
.局部变量 进程列表, 进程信息型, , "0"
.局部变量 进程数量, 整数型
.局部变量 i, 整数型
进程数量 = 取系统进程列表 (进程列表)
.计次循环首 (进程数量, i)
.如果真 (到大写 (进程列表 [i].进程名称) = “OLlyDBG.EXE” 或 到大写 (进程列表 [i].进程名称) = “CHEATENGINE.EXE” 或 到大写 (进程列表 [i].进程名称) = “IDAG.EXE”)
返回 (真)
.如果真结束
.计次循环尾
返回 (假)
.子程序 检测虚拟机, 逻辑型, 公开, 检测是否运行在虚拟机中
.局部变量 BIOS信息, 文本型
.局部变量 主板信息, 文本型
BIOS信息 = 系统信息类.取BIOS信息()
主板信息 = 系统信息类.取主板信息()
' 检测VMware、VirtualBox等虚拟机特征
.如果真 (寻找文本 (BIOS信息, “VMware”, , 假) > 0 或 寻找文本 (BIOS信息, “VirtualBox”, , 假) > 0)
返回 (真)
.如果真结束
.如果真 (寻找文本 (主板信息, “VMware”, , 假) > 0 或 寻找文本 (主板信息, “VirtualBox”, , 假) > 0)
返回 (真)
.如果真结束
返回 (假)
.子程序 代码自校验, 逻辑型, 公开, 检查程序完整性
.局部变量 文件路径, 文本型
.局部变量 文件大小, 整数型
.局部变量 文件校验和, 文本型
.局部变量 正确校验和, 文本型
文件路径 = 取运行目录 () + “\” + 取执行文件名 ()
文件大小 = 取文件尺寸 (文件路径)
文件校验和 = 取数据摘要 (读入文件 (文件路径))
' 这里应该是预先计算好的正确校验和
正确校验和 = “A1B2C3D4E5F67890123456789012345678”
返回 (文件校验和 = 正确校验和)
.子程序 反内存补丁, , 公开, 防止内存被修改
.局部变量 关键数据地址, 整数型
.局部变量 原始数据, 字节集
.局部变量 当前数据, 字节集
' 保护关键内存区域
关键数据地址 = 取变量地址 (服务器配置.加密密钥)
原始数据 = 指针到字节集 (关键数据地址, 取字节集长度 (服务器配置.加密密钥))
' 定时检查内存完整性
.判断循环首 (真)
程序_延时 (5000)
当前数据 = 指针到字节集 (关键数据地址, 取字节集长度 (服务器配置.加密密钥))
.如果真 (当前数据 ≠ 原始数据)
' 内存被修改,采取保护措施
处理内存篡改()
.如果真结束
.判断循环尾 ()
.子程序 处理内存篡改, , 私有
' 记录安全事件
记录安全日志(“检测到内存篡改攻击”, “安全防护”)
' 采取保护措施
终止进程 (取现行进程ID ())
.子程序 初始化安全防护, , 公开
.局部变量 安全状态, 逻辑型
' 多重安全检测
.如果 (检测调试器())
信息框 (“检测到调试器,程序即将退出”, 0, , )
终止进程 (取现行进程ID ())
.否则
.如果 (检测虚拟机())
信息框 (“检测到虚拟机环境”, 0, , )
.否则
.如果 (代码自校验() = 假)
信息框 (“程序文件已被修改”, 0, , )
终止进程 (取现行进程ID ())
.否则
' 启动反内存补丁监控
启动线程 (&反内存补丁, )
.如果结束
.如果结束
.如果结束
4.2 授权验证逻辑
.版本 2
.支持库 spec
.程序集 授权验证类
.程序集变量 验证状态, 整数型
.程序集变量 最后验证时间, 日期时间型
.程序集变量 验证间隔, 整数型
.子程序 _初始化, , ,
验证间隔 = 300000 ' 5分钟验证一次
验证状态 = 0 ' 0=未验证 1=已验证 2=验证失败
.子程序 启动验证循环, , 公开
启动线程 (&验证循环线程, )
.子程序 验证循环线程, ,
.判断循环首 (真)
程序_延时 (验证间隔)
.如果 (验证状态 = 1)
' 定期心跳验证
.如果 (网络通信类.心跳检测(服务器配置.主服务器地址))
最后验证时间 = 取现行时间 ()
.否则
验证状态 = 2
处理验证失败()
.如果结束
.否则
' 重新验证
.如果 (重新验证())
验证状态 = 1
.否则
验证状态 = 2
.如果结束
.如果结束
.判断循环尾 ()
.子程序 重新验证, 逻辑型, 私有
.局部变量 缓存令牌, 文本型
.局部变量 验证结果, 逻辑型
缓存令牌 = 本地缓存.验证令牌
.如果真 (缓存令牌 = "")
返回 (假)
.如果真结束
验证结果 = 客户端验证类.令牌验证(缓存令牌)
返回 (验证结果)
.子程序 检查功能权限, 逻辑型, 公开
.参数 功能名称, 文本型
.局部变量 用户等级, 整数型
.局部变量 功能权限, 整数型
.如果真 (验证状态 ≠ 1)
返回 (假)
.如果真结束
用户等级 = 取用户等级()
功能权限 = 获取功能权限(功能名称)
返回 (用户等级 ≥ 功能权限)
.子程序 获取功能权限, 整数型, 私有
.参数 功能名称, 文本型
.局部变量 权限映射, 文本型
' 从服务器获取功能权限配置
权限映射 = “高级功能:2,管理功能:3,开发者功能:4”
.判断开始 (功能名称 = “高级功能”)
返回 (2)
.判断 (功能名称 = “管理功能”)
返回 (3)
.判断 (功能名称 = “开发者功能”)
返回 (4)
.默认
返回 (1) ' 基础功能
.判断结束
.子程序 处理验证失败, , 私有
.局部变量 失败次数, 整数型, 静态
.局部变量 处理方式, 整数型
失败次数 = 失败次数 + 1
.判断开始 (失败次数 = 1)
' 第一次失败,仅提示
信息框 (“网络验证失败,部分功能受限”, 0, , )
.判断 (失败次数 = 2)
' 第二次失败,限制更多功能
信息框 (“验证多次失败,功能受限”, 0, , )
.判断 (失败次数 ≥ 3)
' 多次失败,退出程序
信息框 (“验证服务不可用,程序即将退出”, 0, , )
终止进程 (取现行进程ID ())
.默认
.判断结束
五、完整应用示例
5.1 主程序集成
.版本 2
.支持库 iext
.程序集 主程序窗口
.程序集变量 验证系统, 客户端验证类
.程序集变量 安全防护, 安全防护类
.程序集变量 授权验证, 授权验证类
.子程序 __启动窗口_创建完毕
' 初始化安全防护
安全防护.初始化安全防护()
' 初始化验证系统
验证系统 = 创建对象 (“客户端验证类”)
授权验证 = 创建对象 (“授权验证类”)
' 启动验证循环
授权验证.启动验证循环()
' 检查本地缓存
.如果 (检查本地缓存())
' 自动登录
处理自动登录()
.否则
' 显示登录窗口
显示登录窗口()
.如果结束
.子程序 检查本地缓存, 逻辑型
.局部变量 缓存时间, 日期时间型
.局部变量 当前时间, 日期时间型
.如果真 (本地缓存.验证令牌 = "")
返回 (假)
.如果真结束
缓存时间 = 本地缓存.最后验证时间
当前时间 = 取现行时间 ()
' 检查缓存是否过期
.如果真 (取时间间隔 (当前时间, 缓存时间, #秒) > 本地缓存.缓存有效期)
返回 (假)
.如果真结束
返回 (真)
.子程序 处理自动登录
.局部变量 验证结果, 逻辑型
验证结果 = 授权验证.重新验证()
.如果 (验证结果)
' 自动登录成功
显示主界面()
.否则
' 自动登录失败,显示登录窗口
显示登录窗口()
.如果结束
.子程序 _登录按钮_被单击
.局部变量 用户名, 文本型
.局部变量 密码, 文本型
.局部变量 验证结果, 逻辑型
用户名 = 用户名编辑框.内容
密码 = 密码编辑框.内容
.如果真 (用户名 = "" 或 密码 = "")
信息框 (“请输入用户名和密码”, 0, , )
返回 ()
.如果真结束
' 显示验证中状态
登录按钮.禁止 = 真
验证状态标签.标题 = “正在验证...”
' 执行登录验证
验证结果 = 验证系统.验证登录(用户名, 密码, “SOFTWARE_ID_001”)
.如果 (验证结果)
验证状态标签.标题 = “验证成功”
程序_延时 (1000)
隐藏登录窗口()
显示主界面()
.否则
验证状态标签.标题 = “验证失败”
登录按钮.禁止 = 假
.如果结束
.子程序 _高级功能按钮_被单击
.局部变量 权限检查, 逻辑型
权限检查 = 授权验证.检查功能权限(“高级功能”)
.如果 (权限检查)
' 执行高级功能
执行高级功能()
.否则
信息框 (“您没有权限使用此功能”, 0, , )
.如果结束
.子程序 显示主界面
主窗口.可视 = 真
主窗口.位置 = 1 ' 居中显示
' 更新用户信息
更新用户界面()
.子程序 更新用户界面
.局部变量 用户信息, 文本型
.局部变量 到期时间, 文本型
用户信息 = 本地缓存.用户信息
到期时间 = 到文本 (客户端信息.到期时间)
用户名标签.标题 = “欢迎: ” + 用户信息
到期时间标签.标题 = “到期时间: ” + 到期时间
.子程序 记录安全日志, , 公开
.参数 日志内容, 文本型
.参数 用户名, 文本型
.局部变量 日志文件, 文本型
.局部变量 日志内容完整, 文本型
日志文件 = 取特定目录 ( #系统桌面 ) + “\security_log.txt”
日志内容完整 = “[” + 时间到文本 (取现行时间 (), ) + “] ” + 用户名 + “: ” + 日志内容 + #换行符
写到文件 (日志文件, 到字节集 (日志内容完整), 真)
5.2 配置管理模块
.版本 2
.程序集 配置管理类
.程序集变量 配置文件路径, 文本型
.子程序 _初始化, , ,
配置文件路径 = 取运行目录 () + “\config.ini”
.子程序 保存配置, 逻辑型, 公开
.参数 配置节, 文本型
.参数 配置项, 文本型
.参数 配置值, 文本型
.局部变量 写入结果, 逻辑型
写入结果 = 写配置项 (配置文件路径, 配置节, 配置项, 配置值)
返回 (写入结果)
.子程序 读取配置, 文本型, 公开
.参数 配置节, 文本型
.参数 配置项, 文本型
.参数 默认值, 文本型, 可空
.局部变量 配置值, 文本型
配置值 = 读配置项 (配置文件路径, 配置节, 配置项, 默认值)
返回 (配置值)
.子程序 保存用户配置, 逻辑型, 公开
.参数 用户名, 文本型
.参数 记住密码, 逻辑型
.参数 自动登录, 逻辑型
写配置项 (配置文件路径, “User”, “Username”, 用户名)
写配置项 (配置文件路径, “User”, “RememberPassword”, 到文本 (记住密码))
写配置项 (配置文件路径, “User”, “AutoLogin”, 到文本 (自动登录))
返回 (真)
.子程序 读取用户配置, 用户配置类型, 公开
.局部变量 用户配置, 用户配置类型
用户配置.用户名 = 读配置项 (配置文件路径, “User”, “Username”, “”)
用户配置.记住密码 = 到逻辑 (读配置项 (配置文件路径, “User”, “RememberPassword”, “假”))
用户配置.自动登录 = 到逻辑 (读配置项 (配置文件路径, “User”, “AutoLogin”, “假”))
返回 (用户配置)
.数据类型 用户配置类型
.成员 用户名, 文本型
.成员 记住密码, 逻辑型
.成员 自动登录, 逻辑型
六、服务器端接口示例
6.1 PHP 服务器端验证接口
<?php
/**
* 易语言网络验证服务器端
* 使用PHP + MySQL实现
*/
class NetworkAuthServer {
private $db;
private $encrypt_key = "B2E3A7F8C9D1E5F6A8B3C4D5E6F7A8B9";
public function __construct() {
$this->connectDatabase();
}
private function connectDatabase() {
$this->db = new mysqli("localhost", "username", "password", "auth_system");
if ($this->db->connect_error) {
die("数据库连接失败: " . $this->db->connect_error);
}
$this->db->set_charset("utf8");
}
/**
* 处理客户端请求
*/
public function handleRequest() {
$input = file_get_contents("php://input");
// 解密请求数据
$decrypted_data = $this->aesDecrypt($input, $this->encrypt_key);
$request_data = json_decode($decrypted_data, true);
if (!$request_data) {
$this->sendResponse(400, "无效的请求数据");
return;
}
$action = $request_data['action'] ?? '';
switch ($action) {
case 'login':
$this->handleLogin($request_data);
break;
case 'heartbeat':
$this->handleHeartbeat($request_data);
break;
case 'token_verify':
$this->handleTokenVerify($request_data);
break;
default:
$this->sendResponse(404, "未知的操作类型");
}
}
/**
* 处理登录请求
*/
private function handleLogin($data) {
$username = $data['username'] ?? '';
$password_hash = $data['password'] ?? '';
$software_id = $data['software_id'] ?? '';
$machine_code = $data['machine_code'] ?? '';
$timestamp = $data['timestamp'] ?? '';
$nonce = $data['nonce'] ?? '';
// 验证签名
if (!$this->verifySignature($data, $timestamp, $nonce)) {
$this->sendResponse(403, "签名验证失败");
return;
}
// 查询用户信息
$stmt = $this->db->prepare("SELECT * FROM users WHERE username = ? AND status = 1");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
$this->sendResponse(401, "用户不存在或已被禁用");
return;
}
$user = $result->fetch_assoc();
// 验证密码
$stmt = $this->db->prepare("SELECT password FROM user_passwords WHERE user_id = ? ORDER BY created_at DESC LIMIT 1");
$stmt->bind_param("i", $user['id']);
$stmt->execute();
$password_result = $stmt->get_result();
$password_data = $password_result->fetch_assoc();
if (!$password_data || !password_verify($password_hash, $password_data['password'])) {
$this->sendResponse(401, "密码错误");
return;
}
// 检查用户权限
if (!$this->checkUserPermission($user['id'], $software_id)) {
$this->sendResponse(403, "用户没有该软件的使用权限");
return;
}
// 生成访问令牌
$token = $this->generateToken($user['id'], $machine_code);
// 返回成功响应
$response_data = [
'user_id' => $user['id'],
'username' => $user['username'],
'user_level' => $user['user_level'],
'expire_time' => $user['expire_time'],
'token' => $token,
'machine_code' => $machine_code
];
$this->sendResponse(200, "登录成功", $response_data);
}
/**
* 处理心跳检测
*/
private function handleHeartbeat($data) {
$token = $data['token'] ?? '';
if (!$this->validateToken($token)) {
$this->sendResponse(401, "令牌无效");
return;
}
$this->sendResponse(200, "心跳检测成功");
}
/**
* 生成响应数据
*/
private function sendResponse($code, $message, $data = null) {
$response = [
'code' => $code,
'message' => $message,
'data' => $data,
'timestamp' => time()
];
// 生成签名
$response['signature'] = $this->generateSignature($response);
$json_response = json_encode($response);
$encrypted_response = $this->aesEncrypt($json_response, $this->encrypt_key);
header('Content-Type: application/json');
echo $encrypted_response;
}
/**
* AES加密
*/
private function aesEncrypt($data, $key) {
$method = 'AES-256-ECB';
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA);
return base64_encode($encrypted);
}
/**
* AES解密
*/
private function aesDecrypt($data, $key) {
$method = 'AES-256-ECB';
$decrypted = openssl_decrypt(base64_decode($data), $method, $key, OPENSSL_RAW_DATA);
return $decrypted;
}
/**
* 验证请求签名
*/
private function verifySignature($data, $timestamp, $nonce) {
$signature = $data['signature'] ?? '';
$data_string = json_encode($data) . $timestamp . $nonce . "SECRET_KEY_123456";
$calculated_signature = md5($data_string);
return $signature === $calculated_signature;
}
/**
* 生成响应签名
*/
private function generateSignature($response) {
$data_string = $response['data'] ? json_encode($response['data']) : '';
$signature_string = $data_string . $response['timestamp'] . "SECRET_KEY_123456";
return md5($signature_string);
}
}
// 启动服务器
$server = new NetworkAuthServer();
$server->handleRequest();
?>
总结
通过本文的完整实现,我们构建了一个功能完善的易语言网络验证系统,具备以下特点:
- 安全性 – 多层加密、签名验证、反调试保护
- 稳定性 – 心跳检测、自动重连、备用服务器
- 灵活性 – 模块化设计、可配置参数、功能权限控制
- 防破解 – 代码自校验、内存保护、虚拟机检测
这套系统可以有效保护软件版权,防止未授权使用,同时提供良好的用户体验。
© 版权声明
THE END














暂无评论内容