使用 LuaJit 和 FFI 进行 OpenSSL 加解密

我正在尝试使用 LuaJIT 中的 FFI 加密和解密 OpenSSL - 我尝试了很多不同的变化,但是我不是很成功。我的代码似乎总是返回空字符串。

我尝试按照 OpenSSL 文档中描述的模式进行:https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_decrypt.html

    local ffi = require "ffi"
    ffi.cdef[[
      EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
      void *malloc(size_t size);
      void free(void *ptr);

      int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
      int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);

      int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
      int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
    ]]

    local s = "hello world"
    local s_len = #s
    local out_len1 = ffi.new("size_t[1]")

    local ctx = ffi.C.EVP_PKEY_CTX_new(gen_key, nil)
    if not ctx then
      return nil
    end

    if ffi.C.EVP_PKEY_encrypt_init(ctx) == 0 then
      return nil
    end

    if ffi.C.EVP_PKEY_encrypt(ctx, nil, out_len1, s, s_len) == 0 then
      return nil
    end

    local buf = ffi.new("unsigned char[?]", out_len1[0])

    if ffi.C.EVP_PKEY_encrypt(ctx, buf, out_len1, s, s_len) == 0 then
      return nil
    end

    local s = ffi.string(buf, out_len1[0])
    local s_len = #s
    local out_len2 = ffi.new("size_t[1]")

    if ffi.C.EVP_PKEY_decrypt_init(ctx) == 0 then
      return nil
    end

    if ffi.C.EVP_PKEY_decrypt(ctx, nil, out_len2, s, s_len) == 0 then
      return nil
    end

    local buf = ffi.new("unsigned char[?]", out_len2[0])
    if ffi.C.EVP_PKEY_decrypt(ctx, buf, out_len2, s, s_len) == 0 then
      return nil
    end

    return ffi.string(buf, out_len2[0])
点赞
用户134758
用户134758

我认为你的代码缺失了某些类型的声明,如 EVP_PKEY_CTXEVP_PKEY等。你需要添加这些数据类型的定义。基本上,ffi.cdef 定义了所有将通过 FFI 使用的函数名,因此 LuaJIT 可以解析它们。

另一方面,对这些函数的调用应该通过实际实现这些函数的库,例如 OpenSSL,而不是 ffi.C。C 命名空间用于访问 libc 以及其他 C 库,例如 libmlibdl。例如:

local ffi = require("ffi")
local ssl = ffi.load("ssl")

ffi.cdef[[
struct evp_pkey_ctx_st {

};
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;

struct evp_pkey_st {

};
typedef struct evp_pkey_st EVP_PKEY;

EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *key, void *b);
]]

local ctx = ssl.EVP_PKEY_CTX_new(gen_key, nil)
if ctx then
   print("ctx created")
else
   return nil
end
2016-03-11 01:43:38