api
* 必要物品
1. signkey
2. encryptKey
3. encryptIV
4. APIURL
---
* 加密範例(php版)(以取得遊戲連結為範例)
```php
$signKey = '{signkey}';
$encryptKey = base64_decode('{encryptKey}');
$encryptIV = base64_decode('{encryptIV}');
// 代理識別碼
$agentCode = 1234;
// GAME API 請求網址
$apiurl = 'http://{APIURL}/api/game';
$requestData = [
'ns' => 'player',
'work' => 'forwardRecreation',
'version' => '0.0.1',
'data' => [
'playerAccount' => 'test5566player',
'homeUrl' => 'www.nba.com',
'gameRuleUrl' => 'www.nba.com'
]
];
$content = json_encode($requestData);
// 開始加密
$dataLen = strlen($content);
$remainder = $dataLen % 16;
if ($remainder != 0) {
$content .= str_repeat(chr(0), 16 - $remainder);
}
$rawData = openssl_encrypt($content, 'AES-256-CBC', $encryptKey, OPENSSL_ZERO_PADDING, $encryptIV);
// 製作簽名資料
$sign = openssl_digest($rawData . $signKey, 'sha512');
// 送出請求 header 需包含 Agent-Code 及 Sign
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $apiurl,
CURLOPT_HEADER => false,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Agent-Code: ' . $agentCode,
'Sign: '. $sign,
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $rawData
]);
$rawData = curl_exec($ch);
curl_close($ch);
```
* 解密範例(php版) - api回應的資料作解密
```php
$signKey = '{signkey}';
$encryptKey = base64_decode('{encryptKey}');
$encryptIV = base64_decode('{encryptIV}');
// 從 response header 中取得簽名檔
$originSign = '我是簽名檔'; //API回傳header中的Sign
$rawData = '我是加密後的資料';//API回傳的已加密資料
// 驗證簽名檔是否正確
$sign = openssl_digest($rawData . $signKey, 'sha512');
if ($sign != $originSign) {
throw new Exceptin('簽名檔驗證錯誤');
}
// 執行解密
$decryptData = trim(openssl_decrypt($rawData, 'AES-256-CBC',
$encryptKey, OPENSSL_ZERO_PADDING, $encryptIV));
$responseData = json_decode($decryptData, true);
```
* 解密後結果
```
================== 最後結果 ==================
最後 $responseData 的值應如下
[
'errorCode' => 0,
'message' => 'OK',
'url' => 'http://play.url?authToken=xxxxxxxxxxxxxxxxxxxx'
]
```
---
* 更多
歡迎提供其他版本的範例 : java / C# / golang / node-js 版
---
* 錯誤代碼
| errorCode| message | description | need you |
| -------- | --------| -------- | -------- |
| 0 | OK | nothing wrong | nothing |
| 1001 | | 簽名驗證失敗 | 確認Sign簽名是否正確 |
| 1002 | | server解密失敗 | 確認加密金鑰是否正確加密 |
| 1004 | | agent key disabled | 請聯絡custom support|
| 2001 | | ns field wrong format | 檢查ns欄位是否合法 |
| 2002 | | work field | 檢查欄位的值內容是否合法 |
| 2003 | | version field | 檢查欄位的值內容是否為0.0.1 |
| 2004 | | playerAccount field | 檢查欄位的值內容是否合法 &長度是否合法 |
| 2005 | | url format | 檢查欄位的值內容是否合法 |
| 2006 | | nickname format | 檢查欄位的值內容是否合法 |
| 2007 | | email format | 檢查欄位的值內容是否合法(RFC2822) |
| 2008 | | billnumber format | 檢查欄位的值內容是否合法 , prefix is agentCode |
| 2009 | | amount format | 檢查欄位的值內容是否合法, deposit only allow integer / withdraw allow integer & double |
| 2010 | | time format | 檢查欄位的值內容是否合法, Y-m-d H:i:s |
| 3001 | | not exist account | create first and then use it |
| 3002 | | account already exist | duplicate create |
| 3003 | | logout player failed | |
| 3004 | | trial account over limit | |
| 4001 | | transfer type not valid ||
| 4002 | | transfer balance should not equal zero. | check transfer balance |
| 4003 | | lookup transfer record failed | check again or contact customer support |
| 4004 | | player balance insufficient | check player balance |
| 4005 | | transfer failed | try again or contact customer support |
| 5001 | | start page | vaild : integer and >0 |
| 5002 | | items each page | vaild: 100~2000 |
| 6001 | | starttime not over or equal endtime | check starttime |
| 6002 | | date only allow today - 30 days | check date|
| 6003 | | time format range limit 24 hours | valid time format & range |
| 8001 | | unknow service | check ns / work / version valid & work |
| 8004 | | token expired | create new token |
| 8009 | |game url not set | set game url |
| 9999 | | others error | contact customer support |
---
* FAQ
1. 若 Header中沒有傳入 名為Agent-Code, Sign 任一項的Header,則 Http 狀態碼回傳 401,錯誤訊息會放在 Header Message 裡
2. 利用 Header Agent-Code 取得系統中 Agent-Code 的相關資訊,若無法取得,則 Http 狀態碼回傳 401,錯誤訊息會放在 Header Message 裡簽名無效狀況
3. 確認1,2點皆無問題後,進行簽名驗證,若驗證失敗則回傳加密後的資料 errorCode=1001 => 解密失敗
4. 確認1,2,3點皆無問題後,進行資料解密,若失敗回傳加密後的資料 errorCode=1002
5. 請確認傳入的參數和值沒有多餘的空白
---
* JAVA版
```
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher
import groovy.json.JsonBuilder
JsonBuilder builder = new JsonBuilder()
builder(
{
"ns" "player"
"work" "createPlayer"
"version" "0.0.1"
"data" {
"account" "abc1234567890"
"nickname" "haabc1234567890"
"email" "abc@test.com"
}
}
)
def plainText = builder.toString()
def encryptKey = encryptKey.decodeBase64()
def ivSpec = encryptIV.decodeBase64()
def cipher = Cipher.getInstance("AES/CBC/NoPadding")
int blockSize = cipher.getBlockSize()
byte[] dataBytes = plainText.getBytes()
int length = dataBytes.length
if (length % blockSize != 0) {
length = length + (blockSize - (length % blockSize));
}
byte[] newPlainText = new byte[length]
System.arraycopy(dataBytes, 0, newPlainText, 0, dataBytes.length)
SecretKeySpec key = new SecretKeySpec(encryptKey, "AES")
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivSpec))
def encryptedStr = cipher.doFinal(newPlainText).encodeBase64().toString()
```