跳轉至

安全变量

介紹

此頁面描述了Hercules的安全變數功能。
在使用安全變數功能之前,您必須先設置Hive SDK。
安全變數具有以下特徵:

  • 這是一個加密的值在記憶體中,以便外部工具無法檢索。
  • 即使加密值被篡改,讀取時也會進行驗證。
  • 支援的語言包括 C/C++ 和 C# (Unity)。

如何使用安全變數

C# (Unity)

  • 基本上,C# 中可用的数据类型可以用作泛型类。
  • 每种数据类型都有相应的安全数据类型,如下所示。
  • 由于所有基本类型都被转换为 8 字节类型,因此建议使用 8 字节类型,例如使用 long 代替 int,使用 double 代替 float。
基本類型 安全類型 基本類型 安全類型
bool HerculesVar<bool> int HerculesVar<int>
char HerculesVar<char> uint HerculesVar<uint>
sbyte HerculesVar<sbyte> long HerculesVar<long>
byte HerculesVar<byte> ulong HerculesVar<ulong>
short HerculesVar<short> float HerculesVar<float>
ushort HerculesVar<ushort> double HerculesVar<double>
string HerculesString
// 以下兩段代碼執行相同的操作並分配一個新對象。
HerculesVar x = 100;
HerculesVar y = new HerculesVar(100);

// 值是从安全变量复制到普通变量的。
int a = x;
// 旧对象分配给 y 的内存被释放,并且新的对象被重新分配给 y。
y = 300;
// 更改 y 的值。 (y 应该已经被分配了一个对象,这种类型的分配比上面的快。)
y.Set(300);

// y 被重新分配為 x 的值。 x 和 y 都開始參考與原始分配給 x 的對象不同的對象。 
y = (int)x;

// 注意:y 將參考 x。如果您使用 Set 函數,則兩個值都會被替換。
// 如果在直接操作無符號類型安全變量時發生構建錯誤,
// 則必須在常量後指定 U,或者應使用顯式類型轉換。(如 1U 或 (uint)1)
// 對於經常更新的值,使用 obj.Set(v); 形式會更有利於性能。
y = x;

// 字串可以這樣使用:只有內存中的字串是受保護的。
// 當指派一個靜態字串如“TEST”時,原始字串可能會暴露給代碼。
HerculesString securityString = <從伺服器下載或動態生成的字串值>;
string plainString = securityString;

iOS, Android

  • 在 C 的情況下,每當您保存或讀取變量的值時,必須直接調用 API,因此建議使用 C++。C++ 定義了一個模板類。
  • 如果可能,建議將安全變量用作全局變量,或在分配和釋放不太頻繁的地方使用它。
  • 不要將 include 語句放在 extern "C" 區塊內。
  • 應在 Hive SDK 初始化後使用。
#include "Hercules.h"

class CUserInfo {
public:
    CHercules hp;
    CHercules mp;
    CHercules critical;
};

// 如果它被用作全局变量,则会出现问题,因为该变量在 Hive SDK 初始化之前尝试被初始化。
// CHercules g_temp;

// 當作為全局變量使用時,請以指針的形式聲明如下。
CUserInfo *g_user;
CHercules *g_var;
CHerculesString *g_string;

void BeginBattle() {
    // 創建一個安全變量。 (例如:在遊戲中開始戰鬥時)
    g_user = new CUserInfo;
    g_var = new CHercules;
    g_string = new CHerculesString(<從伺服器下載或動態生成的字符串值>);
}

void EndBattle() {
    // 刪除安全變數。 (例如:在遊戲中戰鬥結束時)
    delete g_user;
    delete g_var;
    delete g_string;
    g_user = nullptr;
    
}

void Sample()
{
    // 可以以任何形式进行赋值,如下所示。
    int localvar = 0;
    CHercules x = localvar;
    *g_var = localvar;
    *g_var = x + 2;
    g_user->hp = 100;

    // 當指派一個靜態字串如 “TEST” 時,原始字串可能會暴露給程式碼。
    CHerculesString localString1 = <從伺服器下載的新字串或動態生成>; // 初始化為字串
    CHerculesString localString2 = *g_securityString; // 初始化為 CHerculesString 物件
    std::string localString = *g_securityString; // CHerculesString 轉換為 std::string
    localString2 = localString1; // CHerculesString 轉換為 CHerculesString
    localString1 = localString.c_str(); // std::string 轉換為 CHerculesString
}
#include "Hercules.h"

HERCULES g_x;
HERCULES g_y;
HERCULES g_str;

void StartApp() {
    // Creates a secure variable.
    // Can be used by putting basic types and structure variables.
    int var = 0;
    g_x = HerculesAddVar(&var, sizeof(var));
    g_y = HerculesAddVar(&var, sizeof(var));

    // 當分配一個靜態字符串如“TEST”時,原始字符串可能會暴露給代碼。
    g_str = HerculesAddString(<從伺服器下載或動態生成的字符串>);
}

void Sample()
{
    // 獲取 x 的值並將其存儲在 y 中。此時,每個函數中設置的第二個參數
    // 必須是與調用 HerculesAddVar 時設置的大小相同的變量。
    int var;
    HerculesGetVar(g_x, &var);
    HerculesSetVar(g_y, &var);

    // 在你将安全字符串获取为常规字符串后,你需要使用 HerculesFreeMem 函数释放它。
    char *str = HerculesGetString(g_str);
    HerculesFreeMem(str);

    // 在分配新的字符串变量之前,必须使用 HerculesRemoveVar 函数将其删除。
    HerculesRemoveVar(g_str);
    g_str = HerculesAddString(<从服务器下载的新字符串或动态生成的字符串>);
}

參考 (C++)

  • 當安全變數被初始化為一個值時使用它。(對象已分配的狀態)
  • 將其用作最終結果的賦值,該結果是在所有必要計算完成後生成的。
  • 請參考下面的例子。(C++ 有運算子重載。)
// CHercules *securityVar = ...

int sum = 0;
int values[5] = {5, 4, 6, 8, 11};

for(int i = 0; i < 5; i++)
    sum += values[i];

*securityVar += sum;
// CHercules *securityVar = ...

int values[5] = {5, 4, 6, 8, 11};

for(int i = 0; i < 5; i++)
    *securityVar += values[i];