為skynet的crypt庫擴充套件一些加密(摘要)演算法支援
改造起因
在上篇文章, 我描述了為skynet
新增穩定的websocket
支援的起始並闡述了這麼做的原因.
這幾天在測試的時候發現, 當使用skynet
內建的httpc庫的時候會遇見crypt
缺少一些我需要用到的演算法(例如: crc
、sha256
、hmac_sha256
等等).
這裡完全可以假設開發者在框架選型的時候沒發現這個問題, 那可能會到開發中期需要第三方平臺接入或擴充套件不同架構的時候才可能會發現了.
顯然這將會在無形之中就會給一個專案引入不可預料的穩定性因素. 為了儘可能的避免這個因素, 擴充套件一些常見的加密(摘要)演算法支援是必不可少的.
首選方案肯定使用已經成熟的庫. 但是很可惜, lua5.3沒有較為可靠並且現成的實現庫可以fork
而且可以用來參考的庫僅有: luajit
利用ffi
實現的庫、OpenSSL
的實現. 然而這些無法直接或間接移植到lua 5.3.
這是目前遇到的最壞的情況! 最終, 我們只能用Lua的C API來粘合C語言的Crypt實現來完成Lua版本的Crypt擴充套件庫改造工作.
改造開始
我在網上尋找一段時間後發現一個比較不錯的Lua sha實現.
這份程式碼包含md5
、sha128
、sha384
、sha512
的C實現, 其用大量的巨集來完成Lua注入動作. 可見我們需要做的第一件事情就是去掉這些不易閱讀的巨集定義.
我們知道skynet
的luaclib-src/lsha1.c
檔案中已經存在了一份sha1實現. 那麼我們可以保留sha1, 僅僅提取sha2部分的sha256
sha512
的實現.
sha2在改造成標準Lua Model實現後可維護性大大提升, 我們將其命名為lsha2.c
與lsha2.h
來描述顯然再好不過. 這時候, 我們已經可以使用這些演算法進行測試了.
大家都知道HMAC
是一種雜湊
演算法, 目前這種雜湊
演算法的hmac_256
與hmac_512
實現已經在很多雲平臺廣為使用. 一個較為明顯的例子就是騰訊雲.
在lsha1.c
的檔案內已經有了一份HMAC
實現程式碼, 我們將xor_str
演算法拷貝到lsha2
檔案中. 就可以簡單的完成擴充套件.
這裡需要知道的是, sha128
與sha256
的Block都可以使用64, 但是hmac_sha512
block
的長度是128
. 所以我們為它單獨在內部多寫了一份程式碼方便維護.
參照lsha1.c
的hmac_sha128
實現方法擴充套件hmac_256
與hmac_512
非常簡單. 基本上就是改block
與Lua Model編寫. 很快就能完成.
skynet的3rd
目錄下已經支援md5
. 雖然不知道大家怎麼用的, 但是我使用起來感覺非常不便. 並且crypt
庫支援的hmac64_md5
目前與其它語言對接也較為不便.
最後我們索性上面提到的程式碼建立lmd5.c
檔案實現一份md5的演算法, 然後參照上面的hmac演算法又實現了一份hmac_md5
. 這樣能讓所有演算法並存於crypt
庫內部.
當你看到這裡! 你肯定以為, 我們的工作已經完成了! 然而這還不夠, 既然已經開始動手. 那麼一些常見的演算法必將都要被納入進來.
我們最後嘗試從redis
的原始碼檔案中拿到crc32
與crc64
的原始碼, 然後直接提取出來改造成為一個單獨的lcrc.c
檔案併為其注入Lua C API.
以上, 完成了crypt
的基本改造.
改造結果
目前測試結果在其它語言集上內容輸出一致. 由於實現使用到是C語言, 效能表現方面自然強過一些lua實現. 所以不用過多考慮效能都問題.
既然已經開源了一份Websocket
實現, 那麼幹脆也開源這份程式碼吧! 至於命名就延續之前的命名: skynet-lua-crypt
.
安裝方法
由於改造涉及到了skynet的luaclib-src
內的檔案修改, 所以編譯方法肯定不能是普通的3rd方式就能完成編譯的.
而且skynet
的一些檔案內部也使用到了這個庫, 我們需要直接修改skynet
的Makefile
檔案完成這個替換動作. 這樣能保證編果更加順利.
為了跟進版本. 我拉取了skynet
的1.2版本程式碼進行測試, 經過我的MacBook Pro編譯與skynet/test/testsha.lua
檔案測試通過並且無副作用.
專案地址
專案地址在這裡. 安裝與替換方式非常簡單. 基本上就是拷貝原始碼與替換Makefile.
並且我在專案內提供了一份Makefile用於直接替換, 這在專案的README
中都有描述. 至於為什麼不提pull request
, 只是覺得沒有那個必要而已.
更多詳細介紹, 請參考專案Release