# java-服务端接入指南

---

## 安全校验

SDK 提供校验游戏包是否被篡改功能,提供实现demo 游戏方可以根据业务修改相关代码或根据接口开发对等的功能。
实现基本思路，就是校验游戏包的 `md5` 值，若设备内的安装包的 `md5` 与4399平台同一版本不符（包括不存在的版本），游戏直接退出。

实现要点如下：
- 检测应该在游戏底层代码内进行，而不应该在 java 层或通过 java 层进行
- 多点检测，且每一处的检测代码可以不同，可以以某种方式混淆
- 处理好网络异常，和本地包找不到线上数据的情况（找不到线上数据，可能也修改了apk版本号）

注意：游戏破解方式多种多样，多数为动态修改内存，而不是修改 apk 的方式，这种方式的破解仅通过md5校验无法检测。
以下是校验需要的线上数据接口。

###  i.接口
> 注意！！不同环境对应的地址不一样， 但请求体参数相同！！！ 请注意使用表单提交参数。

- **POST(调试地址)** `https://m.4399api.com/openapiv2/open-md5.html?is_test=1`
- **POST(正式地址)** `https://m.4399api.com/openapiv2/open-md5.html`
- 请求方式：`Content-Type: application/x-www-form-urlencoded`
- 请求参数：

|参数名      |类型    |方法    |必须   |说明	                |
|-----------|-------|-------|------|----------------------|
|gamekey	|string	|POST   |是     |游戏game_key	         |
|package	|string |POST   |是     |游戏包名	           |
|version	|int	|POST	|是	   |游戏包版本号versionCode |
|channel    |string |POST   |否     |推广渠道标识            |
|md5		|string	|POST	|是	   |游戏包md5	            |
|time		|int	|POST	|是	   |时间戳		            |
|sign		|string |POST   |是     |签名 详见签名规则        |

`sign` 算法如下所示：    

其中`secret_key` 为充值回调秘钥，具体值可联系运营获取，游戏应妥善保存，不应写在 java 代码内。

``` cpp
content += "/open-md5.html&"
content += time + "&"
content += secret_key + "&"
content += "channel=" + channel + "&"
content += "gamekey=" + gamekey + "&"
content += "md5=" + md5 + "&"
content += "package=" + package + "&"
content += "version=" + version
 
//从第11位开始，包含含11位，后面的十个字符(小写字母)
sign = md5(content).substr(10, 10)
```

成功、失败返回结果示例如下：

```json
{
  "code": 200,
  "result": true,
  "message": "OK"
}
```

```json
{
  "code": 601,
  "result": false,
  "message": "参数错误"
}
```

- 返回结果中`code`的所有取值：

|字段名|含义|
|----|----|
|200|OK        |
|601|参数错误|
|602|签名错误|
|604|游戏信息错误|
|605|签名过期|

- 返回结果中`result`的所有取值：

|字段名|含义|
|----|----|
|true|校验通过，包md5正常|
|false|校验失败，包md5异常|

### ii. demo包
以下提供安全检测的一个实例，用 `c++` 实现，但只要不在 java 层，任意语言都是可行和类似的  
[安全校验DEMO下载](https://sdkftp.4399doc.com/external/operate/app-security-jni.zip)

### iii. 如何调试
接入检验服务的游戏可能会遇到测试包的验证问题：游戏开发或测试时，还未提交线上包，或者本地有个与线上版本相同但md5不同的包，按检验机制，此包将不能通过验证。

为此，开发者需要：
- 在接口后追加`is_test`参数，值为`1`，重新编译本地包
- 将本地包的包名、version code、md5提交给运营，进行测试模式配置

建议：如果是开发阶段，开发者可以增加自己的开关用于控制是否开启校验，但是在发**布时务必确认所有开关和`is_test`参数移除**


### iv. md5计算

linux或mac系统下，或者有cygwin/git bash 工具, 使用md5sum工具计算
```
md5sum xxx.apk
```

如果是windows，可使用
```
certutil -hashfile xxx.apk MD5
```
