[Unity][Lua]為tolua#添加第三方Lua加密C庫lua-crypt

背景

Unity 5.6
tolua# 2017.6月前后GitHub版本
Macbook Pro
OSX up-to-date
skynet up-to-date

起因

項目服務(wù)端使用了云風(fēng)的skynet框架,登錄驗證也采用了其中云風(fēng)推薦的流程。原文

實際上第2步的client key同樣需要經(jīng)過DH-Exchange處理。

驗證流程

在圖述流程中,涉及到了base64dh、hmacdes這些編碼/摘要/加密算法。在Lua中,要找到一個包含了以上所有算法的第三方庫并非易事。
所幸的是,“羊毛出在羊身上”。既然是云風(fēng)推薦的一套流程,自然他也實現(xiàn)了包含上訴所有算法的一套第三方庫。
找到skynet工程lualib-src文件夾,其中的lua-crypt.clsha1.c便是其實現(xiàn)。

P.S.
在云風(fēng)的GitHub下還有另一工程lua-crypt。其最后一次更新是在數(shù)年前。
對比源碼發(fā)現(xiàn)其比skynet中的加密庫少實現(xiàn)了幾個加密算法,如hmac-sha1。
因此推薦使用skynet下更為新、更為全的加密庫。

過程

對于如何在各平臺為tolua#添加第三方庫,參考如何編譯各平臺使用的庫:以編譯tolua為例

Mac

從GitHub上獲取lua-crypt.clsha1.c,導(dǎo)入到Xcode工程(位于macnojit中)的tolua文件夾,如教程所示執(zhí)行build_osx.sh腳本(根據(jù)實際情況可能需要賦予腳本可執(zhí)行權(quán)限,即chmod 777 build_osx.sh。另,腳本執(zhí)行目錄是腳本所在目錄,并非文章所寫工程所在目錄)。

如果你這樣做了,那么很遺憾。你會收獲Build Failed。
我們還需要對c文件作適當(dāng)?shù)男薷牟拍苷>幾g。

  1. 把lua-crypt.c中的luaopen_skynet_crypt及l(fā)uaopen_client_crypt函數(shù)刪掉。替換為以下函數(shù):
LUALIB_API int luaopen_crypt(lua_State *L) {
    //luaL_checkversion(L);
    static int init = 0;
    if (!init) {
        // Don't need call srandom more than once.
        init = 1 ;
        srandom(time(NULL));
    }
    luaL_Reg l[] = {
        { "hashkey", lhashkey },
        { "randomkey", lrandomkey },
        { "desencode", ldesencode },
        { "desdecode", ldesdecode },
        { "hexencode", ltohex },
        { "hexdecode", lfromhex },
        { "hmac64", lhmac64 },
        { "hmac64_md5", lhmac64_md5 },
        { "dhexchange", ldhexchange },
        { "dhsecret", ldhsecret },
        { "base64encode", lb64encode },
        { "base64decode", lb64decode },
        { "sha1", lsha1 },
        { "hmac_sha1", lhmac_sha1 },
        { "hmac_hash", lhmac_hash },
        //{ "xor_str", lxor_str },
        { NULL, NULL },
    };
    //luaL_newlib(L,l);
    #if LUA_VERSION_NUM < 502
        luaL_register(L, "crypt", l);
    #else
        luaL_newlib(L, l);
    #endif
    return 1;
}
  1. 將lua-crypt.c中的lxor_str函數(shù)刪掉。
  2. 將lsha1.c中底部的lhmac_sha1函數(shù)前的LUAMOD_API修飾符刪掉。

緣由

  • LUALIB_API是tolua#定義的宏,實際上就是extern關(guān)鍵字。
  • luaL_checkversion()應(yīng)該是云風(fēng)寫的檢查Lua版本的函數(shù)。tolua的寫法是:
 #if LUA_VERSION_NUM < 502
     luaL_register(L, "crypt", l);
 #else
     luaL_newlib(L, l);
 #endif
  • 由于xor_str這種加密算法的實現(xiàn)中使用了Lua5.2及以上的luaL_buffinitsize函數(shù),而tolua#的Lua版本為5.1,所以只能將其割去。
  • LUAMOD_API應(yīng)該是skynet框架中定義的宏,估計同樣也是extern。

這樣,執(zhí)行腳本便不會報錯,并會在build/Release路徑下生成新的tolua.bundle。用其替換Unity項目工程Plugins下的tolua.bundle。在Lua腳本中通過local crypt = require "crypt"引用類庫,執(zhí)行測試。
然后報錯module 'crypt' not found

C#

在tolua#中,添加第三方庫還需要C#端額外的操作。通過參考LuaClient類,其中打開第三方庫的實現(xiàn)是這樣的:

    protected virtual void OpenLibs()
    {
        luaState.OpenLibs(LuaDLL.luaopen_pb);
        luaState.OpenLibs(LuaDLL.luaopen_struct);
        luaState.OpenLibs(LuaDLL.luaopen_lpeg);
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
        luaState.OpenLibs(LuaDLL.luaopen_bit);
#endif

        if (LuaConst.openLuaSocket)
        {
            OpenLuaSocket();            
        }        

        if (LuaConst.openZbsDebugger)
        {
            OpenZbsDebugger();
        }
    }

參照pb庫的打開,依葫蘆畫瓢,得到了解決方案。
對LuaState虛擬機對象調(diào)用如下語句:

//third-party lib
luaState.OpenLibs (LuaDLL.luaopen_crypt);
//添加完庫之后,需要將堆?;謴?fù)
luaState.LuaSetTop (0);

當(dāng)然了,LuaDll.cs中相應(yīng)的也要添加如下定義:


添加定義

值得注意的是,luaopen_crypt正是lua-crypt.c底部定義函數(shù)的函數(shù)名。
作出修改后,便可正常使用了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容