-
Notifications
You must be signed in to change notification settings - Fork 5
使用其他语言实现密钥刷新服务
- WebSocket 服务务必不要使用 🇨🇳中国(不包括🇭🇰港🇲🇴澳🇹🇼台) IP进行连接, 否则您的共享账户可能会面临封锁
- 务必使用自由的Online实现, 否则您的共享账户可能会面临封锁
- 如果你要在本地搭建服务端, 建议您在您的应用程序内实现Dns解析器
- 不要泄露密钥
- 操作不当导致的封禁后果自负
VapeGateway实现起来很简单, 几乎是人人都可以实现. 它分为以下几个部分
- 刷新账户
- 加密
- 响应密钥刷新请求
- 响应心跳包
Example: VapeAccountServiceImpl.java#L157
注意: Body不是Json
你需要向 http://www.vape.gg/auth.php
发送一个POST请求,并携带如下Header (hwid替换成真实的HWID)
User-Agent: Agent_<hwid>
Content-Type: application/x-www-form-urlencoded
Body: email=manthe@example.com&password=fuckyoumanthe&hwid=<manthe's hwid>&v=v3&t=true
Param | Description | Example Value |
---|---|---|
邮箱或者是用户名 | manthe@example.com | |
password | 密码 | password |
hwid | 设备码,请求时和官网配置的一致即可 | FUMANTHE |
v | Vape类型,v3 是伪装成v4, 通常情况不需要修改 |
v3 |
t | 不清楚 | true |
如果凭证正确, 会返回一个33位的Token, 否则是错误码
您需要在服务端中进行判断并返回给母服务端,对应的字符串见 状态码
Code | Description |
---|---|
1 | 凭证错误 |
102 | 账户被封禁 |
1006 | IP被封禁 (Cloudflare) |
一段HTML代码 | Cloudflare 验证码,可能是没配置User-Agent导致的 |
POST http://www.vape.gg/auth.php
User-Agent: Agent_HWID
Content-Type: application/x-www-form-urlencoded
email=example@example.com&password=example&hwid=HWID&v=v3&t=true
警告: 可能会修改的内容
Example: CryptoUtil.java
丁真服务端使用AES/CBC/PKCS5Padding来进行加密
密钥是一个32位的byteArray, 建议使用base64存储
可以使用如下OpenSSL指令快速生成密钥
# encode with Base64
openssl rand -base64 32
# decoded
openssl rand 32 > vape.key
遇到困难? ChatGPT
请使用其他语言实现下述代码
public byte[] getInitializationVector(SecretKey secretKey) {
byte[] iv = new byte[16]; // 128-bit IV
System.arraycopy(secretKey.getEncoded(), 0, iv, 0, iv.length);
return iv;
}
遇到困难? ChatGPT
请使用其他语言实现下述代码
public String encrypt(@NotNull String plaintext, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
IvParameterSpec ivParams = new IvParameterSpec(getInitializationVector(key));
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
byte[] encrypted = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
public String decrypt(String ciphertext, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
IvParameterSpec ivParams = new IvParameterSpec(getInitializationVector(key));
cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
return new String(decrypted);
}
Example: GatewayFilter.java#L22
对传入的请求头 X-Gateway-Secret
进行解密, 如果解密成功且结果为Hello World
即为正确, 否则拒绝连接
Example: GatewayController.java
你需要先实现验证加密密钥
丁真服务端会向密钥刷新服务的 /gateway/token
发送一个GET请求, 密钥刷新服务需要刷新共享账户, 刷新成功后需要将Token加密并返回给母服务端
Response:
{
"token": "<encrypted token>",
"status": "<status>",
"coldDown": {
"time": 0
}
}
Key | Description |
---|---|
token | auth.php返回的Token (加密的) |
status | 状态码 |
coldDown.time | 注入冷却结束时间, Unix时间戳,精确到毫秒 |
GET http://localhost:8080/gateway/token
X-Gateway-Secret: <encrypted-text>
Example: VapeAuthorizeDTO.java#L16
返回值见 错误码
Status | Description |
---|---|
OK | 正确的密钥 |
SERVLET_ERROR | 服务端错误 |
NO_ACCOUNT | 所有的账户都在冷却 |
INCORRECT | 账户密码错误 |
BANNED | 账户被封禁 (102) |
CLOUDFLARE | IP被封禁(1006) |
Example: GatewayController.java#L51
主控服务端会隔一段时间(通常是30min)向被控发送心跳包, 您的服务端通常只需要返回服务器的信息就可以完成响应
要完成这个相应, 您的服务端需要干如下事情
Method: GET
Uri: /gateway/heartbeat
Response
{
"time": 0,
"coldDown": {
"time": 0
},
"implementation": "example/example-gateway"
}
Key | Description |
---|---|
time | 密钥刷新服务器的时间戳 |
coldDown.time | 注入冷却到期时间 |
implementation | 服务端实现名称 |
GET http://localhost:8080/gateway/heartbeat
X-Gateway-Secret: <encrypted-text>
您还可以使用数据库来存储共享账户的信息, 同时, 代理池可能也可以绕过IP封锁.
Website: getvape.today
Example instance: vape.lunarclient.top