Lua脚本加密(二)
如何实现同时支持加密和未加密的 lua 脚本
可以在加密文件的头部,增加标记字符,还可以增加扩展版本号。比如在加密的 Lua 脚本的最开头增加字符
WWW.JESSON32.CN_101
其中 101 可以是版本号,转为两个字节写入文件。
如果有写入的签名,那么就是加密文件,没有就当作未加密的 Lua 脚本。
回到 ngx_http_lua_clfactory_loadfile 函数
ngx_int_t
ngx_http_lua_clfactory_loadfile(lua_State *L, const char *filename)
{
...
status = lua_load(L, ngx_http_lua_clfactory_getF, &lf,
lua_tostring(L, -1));
...
}
lf 被作为上下文传给了ngx_http_lua_clfactory_getF,其中就有文件指针,所以我们可以在 lf 生命之后增加初始化,为了不影响之前的 逻辑,这里我们可以新增一个 ctx。
typedef struct {
ngx_http_lua_clfactory_file_type_e file_type;
int extraline;
FILE *f;
#ifndef OPENRESTY_LUAJIT
int sent_begin;
int sent_end;
size_t begin_code_len;
size_t end_code_len;
size_t rest_len;
union {
char *ptr;
char str[MAX_BEGIN_CODE_SIZE];
} begin_code;
union {
char *ptr;
char str[MAX_END_CODE_SIZE];
} end_code;
#endif /* OPENRESTY_LUAJIT */
char buff[NGX_LUA_READER_BUFSIZE];
FileReaderCtx ctx; // 新增的 context
} ngx_http_lua_clfactory_file_ctx_t;
typedef struct FileReaderCtx {
FILE *fp;
char buf[LUAL_BUFFERSIZE];
int startpos;
int endpos;
unsigned char first;
unsigned char encrypted;
uint64_t pre;
uint64_t key;
uint8_t mod;
uint64_t surplus;
}FileReaderCtx;
在 ngx_http_lua_clfactory_getF 函数中就可以通过 ngx_http_lua_clfactory_file_ctx_t 获取到 ctx 了.
通过 first 获取是否是第一次读取,第一次读取的话,判断前几个字节是否有加密签名。encrypted 就是判断结束后的一个标记,这样下次读取的时候就不用再判断是否是加密文件了。
后面的 key,mod, surplus 都和加密相关。