OpenResty调用salasa20,xsalsa20,xsalsa20poly1305等算法

OpenResty调用salasa20,xsalsa20,xsalsa20poly1305等算法

应项目需求,需要一套xsalsa20实现的加密算法。如果直接用lua实现一套,既浪费精力,又影响性能,总所周知直接使用LuaJIT的FFI方式,可直接调用c语言实现的函数。

经过网上调研,可直接调用libsodium中内置的加密算法,具体c语言实现的开源代码链接如下:https://github.com/jedisct1/libsodium/tree/master/src/libsodium;还有一个lua语言开源的项目:https://github.com/luapower/libsodium。
其中c语言的项目中,有现成的makefile文件,直接make && make install 生成.so动态语言库即可。然后可根据自己的项目需求,找到对应的算法直接调用即可。下面附上部分项目代码:

local ffi = require "ffi"
local lib = ffi.load("/usr/local/project/libsodium.so")


ffi.cdef [[
size_t crypto_secretbox_xsalsa20poly1305_keybytes(void);
size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void);
size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void);
size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void);
const char * crypto_secretbox_xsalsa20poly1305_primitive(void);
int crypto_secretbox_xsalsa20poly1305(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
int crypto_secretbox_xsalsa20poly1305_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
size_t crypto_secretbox_keybytes(void);
size_t crypto_secretbox_noncebytes(void);
size_t crypto_secretbox_zerobytes(void);
size_t crypto_secretbox_boxzerobytes(void);
const char *crypto_secretbox_primitive(void);
int crypto_secretbox(unsigned char *c, const unsigned char *m,
                     unsigned long long mlen, const unsigned char *n,
                     const unsigned char *k);
int crypto_secretbox_open(unsigned char *m, const unsigned char *c,
                          unsigned long long clen, const unsigned char *n,
                          const unsigned char *k);
]]

local _M = { }

_M.keybytes = function() return tonumber(lib.crypto_secretbox_keybytes()) end
_M.noncebytes = function() return tonumber(lib.crypto_secretbox_noncebytes()) end
_M.zerobytes = function() return tonumber(lib.crypto_secretbox_zerobytes()) end
_M.boxzerobytes = function() return tonumber(lib.crypto_secretbox_boxzerobytes()) end
_M.primitive = function() return ffi.string(lib.crypto_secretbox_primitive()) end
_M.secretbox = function(c, m, mlen, n, k)
	mlen = mlen or #m
	c = c or ffi.new("unsigned char[?]", mlen)
	assert(lib.crypto_secretbox(c, m, mlen, n, k) == 0, "crypto_secretbox returned non-zero")
	return c, mlen
end
_M.open = function(m, c, clen, n, k)
	clen = clen or #c
	m = m or ffi.new("unsigned char[?]", clen)
	assert(lib.crypto_secretbox_open(m, c, clen, n, k) == 0, "crypto_secretbox_open returned non-zero")
	return m, clen
end

return setmetatable ( _M , { __call = function(_M, ...) return _M.secretbox(...) end } )
	local key ="password"
    local nonce = "your_norce"
    //strToByte()方法是字符串转char的方法,返回一个table
    local key_table = strToByte(key)
    local nonce_table = strToByte(nonce)
    local str_key=string.char(unpack(key_table))
    local str_nonce=string.char(unpack(nonce_table))
    local param_table=strToByte(field_value)
    local value_table = new_tab(32+#param_table,0)
    for i=1,32 do
        value_table[i]=0;
    end
    for i=1,#param_table do
        value_table[32+i]=param_table[i]
    end
    local str_value=string.char(unpack(value_table))
    local unsigned_char = ffi.typeof("unsigned char[?]")
    local output = ffi.new(unsigned_char,32+#param_table)
    crypto.secretbox(output,str_value, #str_value, str_nonce, str_key)
    local result_table=new_tab(#str_value,0)
    for i=16,#str_value-1 do
        table.insert(result_table,string.format("%02x",output[i]))
    end
    //最后以十六进制的方式输出加密后的结果
    local encryption_data = table.concat(result_table,"")

你可能感兴趣的:(OpenResty)