开发者文档

接口对接文档

全部接口均为 HTTP POST,参数扁平直传,返回统一 JSON(也支持纯文本)。 下面每个接口都给出完整参数表、返回字段与可直接运行的示例代码。

接口总数 40 请求方式 POST 编码 form-urlencoded

开始接入

2 种调用形态

路径式(推荐)

调用码直接拼在路径里,参数扁平直传。

请求地址

POST https://www.skyayue.top/api/{应用ID}/{调用码}

兼容式(老客户端)

用 api 参数指定接口名,业务参数序列化进 data 串后提交。仅下面「兼容接口」分组里的 9 个能力使用这种形态。

请求地址

POST https://www.skyayue.top/api.php?api={接口名}&app={应用ID}

通用参数

所有接口都可以传,是否需要取决于后台的安全配置。

参数类型必填说明
t number 条件 10 位秒级 Unix 时间戳,开启时间戳校验时必填,与服务器差 ≤30s
s string 条件 MD5 签名(32 位小写),开启签名校验时必填
safe_code string 可选 数据验证码,服务端原样返回,用于防中间人篡改

传输与返回

JSON / 文本

成功响应

JSON

{
  "code": 200,
  "id": 1,
  "end_time": "2026-04-10 12:00:00",
  "amount": "30天",
  "available": 2592000,
  "token": "a1b2c3d4...",
  "statecode": "f1e2d3c4...",
  "safe_code": "hello"
}

失败响应

失败时 code 为 201,msg 是可读的原因。

JSON

{ "code": 201, "msg": "卡密不存在" }

文本格式

后台把返回格式设为「文本」时,首行是状态描述,其余每行 键:值。

登录成功
卡密ID:1
到期时间:2026-04-10 12:00:00
卡密时长:30天
剩余时间:2592000
校验密钥:a1b2c3d4
登录状态码:f1e2d3c4

文本格式没有 code 字段,判断成功要靠首行文案,不够稳。 建议统一用 JSON。

加密

请求值 / 返回值可分别开启

支持的算法

算法特点需要配置
RC4对称流式,性能最好,适合高频调用RC4 密钥
Base64 自定义把标准 Base64 表替换成 64 个自定义字符,安全性较低64 字符编码表
DES-ECBDES + PKCS7 填充,安全性中等8 字节密钥
RSA非对称,安全性最高但最慢,有数据长度限制公私钥对

RSA 的方向与常规相反

方向加密方解密方
请求客户端用公钥服务端用私钥
响应服务端用私钥客户端用公钥

分段大小:1024 位密钥加密块 117 字节、解密块 128 字节;2048 位分别为 245 / 256。

请求值编码

加密后的数据还要编码再传输:无编码 / Base64 / HEX。 建议用 HEX —— Base64 里的 + 在 URL 中会被转成空格,导致解密失败。

注意:加密一旦开启,所有参数值(含 t、 s、safe_code)都要加密并编码,漏一个就整体失败。

签名

MD5 · 32 位小写

计算步骤

  1. 把所有参数(排除 s 自身)按发送顺序拼成 k1=v1&k2=v2&…
  2. 末尾追加 &{APPKEY}
  3. 取 MD5(32 位小写),结果就是 s

PHP

$params = ['kami' => $kami, 'imei' => $imei, 't' => (string) time()];
$pair = [];
foreach ($params as $k => $v) { $pair[] = $k . '=' . $v; }
$s = md5(implode('&', $pair) . '&' . $APPKEY);
$params['s'] = $s;

开了加密时顺序不能错

签名用的是加密编码后的值,而且 s 本身也要加密编码后再传输。 正确顺序是:

明文参数 → 逐个加密 → 按规定编码 → 用编码后的值算签名 → 签名也要加密编码 → 提交

双向签名

后台选「双向签名」时,响应还会带 token。 客户端可用 md5(ID + APPKEY + 签名原文 + 到期时间 + 当前日期分钟) 校验响应是否被篡改。

时间戳

±30 秒

规则

开启后所有请求必须带 t,值为 10 位秒级 Unix 时间戳,与服务器时差不得超过 30 秒。开启「校验增强」后,还要求请求时间不得晚于服务器时间(防重放)。

常见失败原因

现象原因
时间戳参数不可为空没带 t
验证数据已失效传了 13 位毫秒时间戳,或日期字符串
验证数据已失效设备时间不准,与服务器偏差超过 30 秒
验证数据已失效开了请求值加密,但 t 没加密(服务端解密失败也报这个)

错误消息

27 条

通用

msg原因
错误的调用 接口路径不存在,或请求方法不是 POST
程序未开启 应用被关闭
接口未开启 该接口在后台未启用
时间戳参数不可为空 开启了时间戳校验,但请求没带 t
验证数据已失效,请重试 时间戳超出 30 秒;或加密算法、密钥与后台不一致
签名参数不可为空 开启了签名校验,但请求没带 s
签名有误 签名计算与服务器结果不一致

卡密

msg原因
卡密不可为空 未传 kami
机器码不可为空 开启了机器码校验,但未传 imei
机器码不合法,因为存在'号 imei 中不能含单引号
卡密不存在 卡密值不存在或已删除
卡密被禁用 后台手动禁用
卡密已到期 已过到期时间
卡密使用次数已达上限 次数卡可用次数已用完
卡密禁止登录 开启了空设备禁登,但该卡密还没绑定设备

设备与 IP

msg原因
请在原设备登录 机器码与绑定的不一致
请在原IP登录 IP 与绑定的不一致
请在原设备操作 解绑时提交的机器码与绑定的不一致

账号

msg原因
账号密码不正确 用户名或密码错误
账号已被禁用 账号被禁用或处于封禁期
账号已到期 账号有效期已过
账号已存在 注册时用户名重复
账号注册频率过快 同 IP 60 秒内注册超过 5 次
QQ未绑定账号 该 openid 未绑定过账号
身份信息错误 QQ 凭据与绑定时不一致

心跳

msg原因
登录状态码不可为空 未传 statecode
登录状态已失效,请重新登录 statecode 已过期,或被同身份的再次登录顶掉

单码卡密

6 个接口

一码一用的验证模式,不需要用户注册。

POST 单码卡密登录 code_kami_login

验证卡密并返回到期时间、token、statecode。

请求参数

参数类型必填说明
kami string 必填 单码卡密值
imei string 条件 机器码,开启机器码验证时必填,不可含单引号
safe_code string 可选 数据验证码,服务端原样返回

返回字段

字段说明
id 卡密 ID
end_time 到期时间
amount 时长描述
available 剩余秒数(次卡为剩余次数-1)
token 二次校验密钥
statecode 心跳凭据
date 服务器日期分钟
imei 绑定设备
change 已解绑次数
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_kami_login' \
  -d 'kami={值}&imei={值}&safe_code={值}&safe_code=hello'
POST 单码心跳验证 code_kami_hb

定时上报维持在线状态,检测顶号与到期。

请求参数

参数类型必填说明
statecode string 必填 登录时返回的状态码
imei string 可选 机器码,传则校验与登录设备一致

返回字段

字段说明
end_time 到期时间
available 剩余秒数

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_kami_hb' \
  -d 'statecode={值}&imei={值}&safe_code=hello'
POST 查询单码卡密 code_query_kami

查询卡密状态,不触发登录、不占用设备数。

请求参数

参数类型必填说明
kami string 必填 单码卡密值

返回字段

字段说明
id 卡密 ID
end_time 到期时间
amount 时长描述
available 剩余量
imei 绑定设备
change 已解绑次数
state 状态(正常/禁用)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_query_kami' \
  -d 'kami={值}&safe_code=hello'
POST 获取卡密核心数据 code_kami_core

读取卡密的 core 字段(Hex 编码)。

请求参数

参数类型必填说明
kami string 必填 单码卡密值

返回字段

字段说明
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_kami_core' \
  -d 'kami={值}&safe_code=hello'
POST 获取在线卡密数量 code_online_kami

统计 10 分钟内活跃的卡密数,无需登录。

返回字段

字段说明
count 在线数量

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_online_kami' \
  -d 'safe_code=hello'
POST 单码以卡充卡 code_kami_recharge

用一张未使用的时长卡为另一张卡续期。

请求参数

参数类型必填说明
kami string 必填 被充值的卡密
card string 必填 用作充值来源的卡密(须未使用、时长型)

返回字段

字段说明
end_time 充值后的到期时间
available 剩余秒数

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_kami_recharge' \
  -d 'kami={值}&card={值}&safe_code=hello'

用户体系

9 个接口

账号注册、登录、充值续费的完整闭环。

POST 用户注册 code_user_reg

注册新账号,账号与密码各不少于 6 位。

请求参数

参数类型必填说明
user string 必填 用户名(≥6 位,字母数字_@.-)
pass string 必填 密码(≥6 位)

返回字段

字段说明
username 注册成功的账号

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_user_reg' \
  -d 'user={值}&pass={值}&safe_code=hello'
POST 用户登录 code_user_login

账号密码登录,返回到期时间与 statecode。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 密码
imei string 条件 机器码,开启机器码验证时必填

返回字段

字段说明
id 用户 ID
username 用户名
end_time 到期时间
available 剩余秒数
token 校验密钥
statecode 心跳凭据
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_user_login' \
  -d 'user={值}&pass={值}&imei={值}&safe_code=hello'
POST 用户心跳验证 code_user_hb

用户在线保活,逻辑同单码心跳。

请求参数

参数类型必填说明
statecode string 必填 登录时返回的状态码

返回字段

字段说明
username 用户名
end_time 到期时间
available 剩余秒数

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_user_hb' \
  -d 'statecode={值}&safe_code=hello'
POST 用户充值卡密 code_recharge

用未使用的卡密为账号续期。

请求参数

参数类型必填说明
user string 必填 用户名
card string 必填 充值卡密(须未使用)

返回字段

字段说明
username 用户名
end_time 充值后到期时间
available 剩余秒数

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_recharge' \
  -d 'user={值}&card={值}&safe_code=hello'
POST 用户修改密码 code_change_pwd

校验原密码后修改,成功后旧状态码全部失效。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 原密码
newpass string 必填 新密码(≥6 位)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_change_pwd' \
  -d 'user={值}&pass={值}&newpass={值}&safe_code=hello'
POST 用户注销账号 code_user_cancel

永久删除账号,不可恢复。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 密码

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_user_cancel' \
  -d 'user={值}&pass={值}&safe_code=hello'
POST 获取用户核心数据 code_user_core

读取账号的 core 字段(Hex)。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 密码

返回字段

字段说明
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_user_core' \
  -d 'user={值}&pass={值}&safe_code=hello'
POST 获取在线用户数量 code_online_user

统计 10 分钟内活跃的账号数。

返回字段

字段说明
count 在线数量

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_online_user' \
  -d 'safe_code=hello'
POST 统一心跳验证 code_hb_any

只传 statecode,服务端自动识别是卡密/用户/QQ。

请求参数

参数类型必填说明
statecode string 必填 登录时返回的状态码

返回字段

字段说明
end_time 到期时间
available 剩余量

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_hb_any' \
  -d 'statecode={值}&safe_code=hello'

QQ 授权

6 个接口

以 openid + access_token 作为凭据的快捷登录。

POST 用户绑定 QQ code_bind_qq

为账号绑定 openid + access_token。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 密码
openid string 必填 QQ openid
access_token string 必填 QQ access_token

返回字段

字段说明
username 用户名

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_bind_qq' \
  -d 'user={值}&pass={值}&openid={值}&access_token={值}&safe_code=hello'
POST 用户 QQ 登录 code_qq_login

用已绑定的 QQ 凭据快捷登录。

请求参数

参数类型必填说明
openid string 必填 QQ openid
access_token string 必填 QQ access_token
imei string 可选 机器码

返回字段

字段说明
id 用户 ID
username 用户名
end_time 到期时间
available 剩余秒数
token 校验密钥
statecode 心跳凭据
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_login' \
  -d 'openid={值}&access_token={值}&imei={值}&safe_code=hello'
POST QQ 凭证心跳 code_qq_hb

用 QQ 凭据 + statecode 维持在线,检测顶号。

请求参数

参数类型必填说明
openid string 必填 QQ openid
access_token string 必填 QQ access_token
statecode string 必填 登录状态码

返回字段

字段说明
username 用户名
end_time 到期时间
available 剩余量

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_hb' \
  -d 'openid={值}&access_token={值}&statecode={值}&safe_code=hello'
POST QQ 凭证取核心数据 code_qq_core

用 QQ 凭据读取账号 core(Hex)。

请求参数

参数类型必填说明
openid string 必填 QQ openid
access_token string 必填 QQ access_token

返回字段

字段说明
core 核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_core' \
  -d 'openid={值}&access_token={值}&safe_code=hello'
POST QQ 凭证改核心数据 code_qq_mod_core

用 QQ 凭据修改 core,长度 ≤1000 的 Hex。

请求参数

参数类型必填说明
openid string 必填 QQ openid
access_token string 必填 QQ access_token
core string 必填 新的核心数据(Hex)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_mod_core' \
  -d 'openid={值}&access_token={值}&core={值}&safe_code=hello'
POST 用户解绑 QQ code_qq_unbind

用账号密码清空 QQ 绑定(不用 QQ 凭据,防盗号)。

请求参数

参数类型必填说明
user string 必填 用户名
pass string 必填 密码

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_unbind' \
  -d 'user={值}&pass={值}&safe_code=hello'

通用风控

3 个接口

卡密与用户都可调用的解绑与禁用。

POST 单码/用户解绑 code_unbind

解绑机器码,允许在新设备登录。受次数与间隔限制。

请求参数

参数类型必填说明
kami string 条件 卡密(与 user 二选一)
user string 条件 用户名(与 kami 二选一)
imei string 必填 当前绑定的机器码

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_unbind' \
  -d 'kami={值}&user={值}&imei={值}&safe_code=hello'
POST IP 解绑 code_ip_unbind

清空卡密或账号的 IP 绑定。

请求参数

参数类型必填说明
kami string 条件 卡密(与 user 二选一)
user string 条件 用户名(与 kami 二选一)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_ip_unbind' \
  -d 'kami={值}&user={值}&safe_code=hello'
POST 禁用卡密/用户 code_disable

远程风控:禁用后立即失效并踢下线。

请求参数

参数类型必填说明
kami string 条件 卡密(与 user 二选一)
user string 条件 用户名(与 kami 二选一)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_disable' \
  -d 'kami={值}&user={值}&safe_code=hello'

程序配置

1 个接口

版本更新检查。(公告与版本号读接口由「程序基础信息」分组提供,不重复列出)

POST 检查更新 code_check_update

对比本地与服务器版本,返回下载地址与更新说明。

请求参数

参数类型必填说明
ver string 必填 客户端当前版本号

返回字段

字段说明
version 服务器版本
upurl 下载地址
upcontent 更新说明
must 是否强制更新(1/0)
hasupdate 是否有新版本(1/0)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_check_update' \
  -d 'ver={值}&safe_code=hello'

数据管理

5 个接口

远程变量、核心数据、云文档。

POST 获取远程变量 code_get_var

按 valueid + valuename 取值,支持卡密模式与用户模式。

请求参数

参数类型必填说明
kami string 条件 卡密模式时必填
user string 条件 用户模式时必填
pass string 条件 用户模式时必填
valueid number 必填 变量 ID
valuename string 必填 变量名

返回字段

字段说明
value 变量内容

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_get_var' \
  -d 'kami={值}&user={值}&pass={值}&valueid=1&valuename={值}&safe_code=hello'
POST QQ 凭证取变量 code_qq_get_var

用 QQ 凭据取该 openid 名下的变量。

请求参数

参数类型必填说明
openid string 必填 QQ openid
access_token string 必填 QQ access_token
valueid number 必填 变量 ID
valuename string 必填 变量名

返回字段

字段说明
value 变量内容

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_qq_get_var' \
  -d 'openid={值}&access_token={值}&valueid=1&valuename={值}&safe_code=hello'
POST 修改远程变量 code_mod_var

不存在则创建,存在则覆盖。

请求参数

参数类型必填说明
kami string 条件 卡密模式时必填
user string 条件 用户模式时必填
pass string 条件 用户模式时必填
valueid number 必填 变量 ID
valuename string 必填 变量名
valuecontent string 必填 变量内容(≤4000)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_mod_var' \
  -d 'kami={值}&user={值}&pass={值}&valueid=1&valuename={值}&valuecontent={值}&safe_code=hello'
POST 修改核心数据 code_mod_core

修改卡密或用户的 core 字段,Hex 编码。

请求参数

参数类型必填说明
kami string 条件 卡密模式时必填
user string 条件 用户模式时必填
pass string 条件 用户模式时必填
core string 必填 新的核心数据(Hex,≤1000)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_mod_core' \
  -d 'kami={值}&user={值}&pass={值}&core={值}&safe_code=hello'
POST 获取云文档 code_cloud_doc

按 token 取云文档内容。

请求参数

参数类型必填说明
token string 必填 文档 token

返回字段

字段说明
title 标题
content 内容

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_cloud_doc' \
  -d 'token={值}&safe_code=hello'

安全功能

1 个接口

客户端完整性校验。

POST 判断应用签名 code_app_sign

校验客户端签名摘要,防 APK 被篡改。未登记期望值时直接放行。

请求参数

参数类型必填说明
autograph string 必填 客户端算出的签名摘要

返回字段

字段说明
valid 是否匹配(1/0)

调用示例

curl -X POST 'https://www.skyayue.top/api/{应用ID}/code_app_sign' \
  -d 'autograph={值}&safe_code=hello'

兼容接口(旧调用形态)

9 个接口

这 9 个能力只在 /api.php?api=xxx 形态下提供,路径式接口未覆盖。请求方式与上面不同,参数要序列化进 data 串。

POST 获取配置 api=ini 兼容

取应用的初始化配置(版本、公告、加密类型、更新地址等)。客户端启动时先调这个。

请求参数

参数类型必填说明
pay number 可选 传 1 时额外返回支付相关字段

返回字段

字段说明
version 版本号
notice 公告
mi_type 加密类型
app_update_url 更新地址
app_update_must 是否强制更新

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=ini&app={应用ID}' \
  -d 'data=pay={值}'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 获取密钥 api=getrc4 兼容

按应用 ID 取 RC4 密钥,用于客户端加密请求。

请求参数

参数类型必填说明
appid number 必填 应用 ID

返回字段

字段说明
rc4 RC4 密钥

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=getrc4&app={应用ID}' \
  -d 'data=appid=1'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 获取文件 api=getfile 兼容

按文件 ID 下载应用绑定的外链文件。

请求参数

参数类型必填说明
id number 必填 文件 ID

返回字段

字段说明
url 文件地址
name 文件名

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=getfile&app={应用ID}' \
  -d 'data=id=1'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST SIG 脚本 api=sig 兼容

取应用的 SIG 脚本内容(易语言等脚本型客户端用)。

返回字段

字段说明
sig 脚本内容

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=sig&app={应用ID}' \
  -d 'data='

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 登录获取应用 api=logongetapp 兼容

用开发者账号密码换取应用密钥,客户端首次接入时用。不需要 APPKEY 签名(拿密钥前没法签)。

请求参数

参数类型必填说明
user string 必填 开发者账号
pass string 必填 开发者密码

返回字段

字段说明
app_key 应用密钥
rc4_key RC4 密钥

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=logongetapp&app={应用ID}' \
  -d 'data=user={值}&pass={值}'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 开启加密取密钥 api=openrc42 兼容

用开发者账号密码把应用切到加密模式并取回密钥。同样不需要 APPKEY 签名。

请求参数

参数类型必填说明
user string 必填 开发者账号
pass string 必填 开发者密码
appid number 必填 应用 ID

返回字段

字段说明
rc4_key RC4 密钥

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=openrc42&app={应用ID}' \
  -d 'data=user={值}&pass={值}&appid=1'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 违规信息上报 api=violationsinfo 兼容

客户端上报违规/异常信息,进后台日志。

请求参数

参数类型必填说明
msg string 必填 上报内容

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=violationsinfo&app={应用ID}' \
  -d 'data=msg={值}'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 易验证脚本 api=ygg 兼容

易验证(易语言验证框架)的对接脚本。

返回字段

字段说明
code 脚本内容

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=ygg&app={应用ID}' \
  -d 'data='

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

POST 易验证卡密登录 api=yyzkmdenglu 兼容

易验证框架的卡密登录入口,语义同 T3 的卡密登录。

请求参数

参数类型必填说明
kami string 必填 卡密

返回字段

字段说明
vip 到期时间戳

调用示例

curl -X POST 'https://www.skyayue.top/api.php?api=yyzkmdenglu&app={应用ID}' \
  -d 'data=kami={值}'

兼容接口的参数要序列化进 data 串;开启加密时整串先加密,再附 sign。

多语言示例

以卡密登录为例

以下假设后台已开启 RC4 + HEX 编码 + 请求签名 + 时间戳校验(推荐组合)。 某项没开就把对应代码删掉。

PHP

<?php
$base   = 'https://www.skyayue.top';
$appId  = 0;
$code   = 'code_kami_login';
$appkey = '你的APPKEY';
$rc4Key = '你的RC4密钥';

function rc4(string $d, string $k): string {
    $s = range(0, 255); $j = 0; $kl = strlen($k);
    for ($i = 0; $i < 256; $i++) {
        $j = ($j + $s[$i] + ord($k[$i % $kl])) & 0xFF;
        [$s[$i], $s[$j]] = [$s[$j], $s[$i]];
    }
    $o = ''; $i = 0; $j = 0;
    for ($n = 0; $n < strlen($d); $n++) {
        $i = ($i + 1) & 0xFF; $j = ($j + $s[$i]) & 0xFF;
        [$s[$i], $s[$j]] = [$s[$j], $s[$i]];
        $o .= chr(ord($d[$n]) ^ $s[($s[$i] + $s[$j]) & 0xFF]);
    }
    return $o;
}

$params = ['kami' => '卡密值', 'imei' => '设备号', 't' => (string) time()];

// 逐值加密 + HEX 编码
$wire = [];
foreach ($params as $k => $v) {
    $wire[$k] = strtoupper(bin2hex(rc4($v, $rc4Key)));
}

// 签名用编码后的值,末尾追加 &APPKEY
$pair = [];
foreach ($wire as $k => $v) { $pair[] = $k . '=' . $v; }
$s = md5(implode('&', $pair) . '&' . $appkey);
$wire['s'] = strtoupper(bin2hex(rc4($s, $rc4Key)));

$ch = curl_init("$base/api/$appId/$code");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($wire),
    CURLOPT_RETURNTRANSFER => true,
]);
$resp = json_decode((string) curl_exec($ch), true);
if (($resp['code'] ?? 0) == 200) {
    echo '到期:' . $resp['end_time'] . PHP_EOL;
    $statecode = $resp['statecode'];  // 后续心跳用
} else {
    echo '失败:' . ($resp['msg'] ?? '未知');
}

Java / Android

Map<String,String> params = new LinkedHashMap<>();
params.put("kami", card);
params.put("imei", deviceId);
params.put("t", String.valueOf(System.currentTimeMillis() / 1000));

// 加密 + HEX
Map<String,String> wire = new LinkedHashMap<>();
for (Map.Entry<String,String> e : params.entrySet()) {
    wire.put(e.getKey(), bytesToHex(rc4(e.getValue().getBytes("UTF-8"), rc4Key)));
}

// 签名
StringBuilder sb = new StringBuilder();
for (Map.Entry<String,String> e : wire.entrySet()) {
    if (sb.length() > 0) sb.append('&');
    sb.append(e.getKey()).append('=').append(e.getValue());
}
sb.append('&').append(appkey);
String s = md5Hex(sb.toString());
wire.put("s", bytesToHex(rc4(s.getBytes("UTF-8"), rc4Key)));

HttpURLConnection conn = (HttpURLConnection) new URL(
        base + "/api/" + appId + "/" + code).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
try (OutputStream os = conn.getOutputStream()) {
    os.write(buildQuery(wire).getBytes("UTF-8"));
}
JSONObject json = new JSONObject(readAll(conn.getInputStream()));
if (json.optInt("code") == 200) {
    String statecode = json.getString("statecode");
    // 起定时器每 60 秒调心跳
} else {
    Log.e("verify", json.optString("msg"));
}

Python

import hashlib, time, requests

APPKEY = '你的APPKEY'
RC4KEY = b'你的RC4密钥'
BASE, APPID, CODE = 'https://www.skyayue.top', 0, 'code_kami_login'

def rc4(data: bytes, key: bytes) -> bytes:
    S = list(range(256)); j = 0
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) & 0xFF
        S[i], S[j] = S[j], S[i]
    out, i, j = bytearray(), 0, 0
    for ch in data:
        i = (i + 1) & 0xFF
        j = (j + S[i]) & 0xFF
        S[i], S[j] = S[j], S[i]
        out.append(ch ^ S[(S[i] + S[j]) & 0xFF])
    return bytes(out)

params = {'kami': '卡密值', 'imei': '设备号', 't': str(int(time.time()))}
wire = {k: rc4(str(v).encode(), RC4KEY).hex().upper() for k, v in params.items()}

sign_src = '&'.join(f'{k}={v}' for k, v in wire.items()) + '&' + APPKEY
wire['s'] = rc4(hashlib.md5(sign_src.encode()).hexdigest().encode(), RC4KEY).hex().upper()

r = requests.post(f'{BASE}/api/{APPID}/{CODE}', data=wire, timeout=15).json()
if r.get('code') == 200:
    print('到期:', r['end_time'])
    statecode = r['statecode']
else:
    print('失败:', r.get('msg'))

Node.js

const crypto = require('crypto');
const axios = require('axios');

const APPKEY = '你的APPKEY';
const RC4KEY = Buffer.from('你的RC4密钥');
const BASE = 'https://www.skyayue.top';
const APPID = 0;
const CODE = 'code_kami_login';

function rc4(data, key) {
  const S = [...Array(256).keys()]; let j = 0;
  for (let i = 0; i < 256; i++) {
    j = (j + S[i] + key[i % key.length]) & 255;
    [S[i], S[j]] = [S[j], S[i]];
  }
  const out = Buffer.alloc(data.length);
  let i = 0; j = 0;
  for (let n = 0; n < data.length; n++) {
    i = (i + 1) & 255; j = (j + S[i]) & 255;
    [S[i], S[j]] = [S[j], S[i]];
    out[n] = data[n] ^ S[(S[i] + S[j]) & 255];
  }
  return out;
}

const params = { kami: '卡密值', imei: '设备号', t: String(Math.floor(Date.now() / 1000)) };
const wire = {};
for (const [k, v] of Object.entries(params)) {
  wire[k] = rc4(Buffer.from(String(v)), RC4KEY).toString('hex').toUpperCase();
}

const signSrc = Object.entries(wire).map(([k, v]) => `${k}=${v}`).join('&') + '&' + APPKEY;
const s = crypto.createHash('md5').update(signSrc).digest('hex');
wire.s = rc4(Buffer.from(s), RC4KEY).toString('hex').toUpperCase();

axios.post(`${BASE}/api/${APPID}/${CODE}`, new URLSearchParams(wire))
  .then(r => {
    if (r.data.code == 200) console.log('到期:', r.data.end_time);
    else console.log('失败:', r.data.msg);
  });

C#

using System.Security.Cryptography;
using System.Text;

var appkey = "你的APPKEY";
var rc4Key = Encoding.UTF8.GetBytes("你的RC4密钥");
var baseUrl = "https://www.skyayue.top";
var appId = 0;
var code = "code_kami_login";

static byte[] Rc4(byte[] data, byte[] key) {
    var s = new byte[256];
    for (int i = 0; i < 256; i++) s[i] = (byte)i;
    int j = 0;
    for (int i = 0; i < 256; i++) {
        j = (j + s[i] + key[i % key.Length]) & 0xFF;
        (s[i], s[j]) = (s[j], s[i]);
    }
    var o = new byte[data.Length];
    int a = 0, b = 0;
    for (int n = 0; n < data.Length; n++) {
        a = (a + 1) & 0xFF; b = (b + s[a]) & 0xFF;
        (s[a], s[b]) = (s[b], s[a]);
        o[n] = (byte)(data[n] ^ s[(s[a] + s[b]) & 0xFF]);
    }
    return o;
}

var p = new Dictionary<string,string> {
    ["kami"] = "卡密值",
    ["imei"] = "设备号",
    ["t"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()
};
var wire = new Dictionary<string,string>();
foreach (var kv in p)
    wire[kv.Key] = Convert.ToHexString(Rc4(Encoding.UTF8.GetBytes(kv.Value), rc4Key));

var src = string.Join("&", wire.Select(kv => $"{kv.Key}={kv.Value}")) + "&" + appkey;
var md5 = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(src))).ToLowerInvariant();
wire["s"] = Convert.ToHexString(Rc4(Encoding.UTF8.GetBytes(md5), rc4Key));

var http = new HttpClient();
var resp = await http.PostAsync($"{baseUrl}/api/{appId}/{code}",
                                 new FormUrlEncodedContent(wire));
Console.WriteLine(await resp.Content.ReadAsStringAsync());

排查建议

对接遇到问题时,先看开发者后台「调用日志」:能看到每次请求的调用码、 返回消息与耗时,比自己猜快得多。