Перейти к содержанию

openssl: Привязка OpenSSL на основе FFI для nginx-module-lua

Установка

Если вы еще не настроили подписку на репозиторий RPM, зарегистрируйтесь. Затем вы можете продолжить с следующими шагами.

CentOS/RHEL 7 или Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-openssl

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-openssl

Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что nginx-module-lua установлен.

Этот документ описывает lua-resty-openssl v1.7.1, выпущенную 13 января 2026 года.


Привязка OpenSSL на основе FFI для LuaJIT, поддерживающая OpenSSL 3.x, 1.1 серии.

Поддержка OpenSSL 1.1.0, 1.0.2 и BoringSSL была прекращена, но они все еще доступны в ветке 0.x.

Статус сборки luarocks opm

Описание

lua-resty-openssl — это библиотека привязки OpenSSL на основе FFI, в настоящее время поддерживает OpenSSL 3.x и 1.1.1 серии.

Синопсис

Эта библиотека во многом вдохновлена luaossl, при этом используется наименование, более близкое к оригинальному API OpenSSL. Например, функция, называемая X509_set_pubkey в C API OpenSSL, будет ожидать существовать как resty.openssl.x509:set_pubkey. CamelCase заменяются на underscore_case, например, X509_set_serialNumber становится resty.openssl.x509:set_serial_number. Еще одно отличие от luaossl заключается в том, что ошибки никогда не выбрасываются с помощью error(), а вместо этого возвращаются как последний параметр.

Каждая таблица Lua, возвращаемая new(), содержит объект cdata ctx. Пользователям не следует вручную устанавливать ffi.gc или вызывать соответствующий деструктор структуры ctx (например, функции *_free).

resty.openssl

Этот мета-модуль предоставляет проверку версии на связанную библиотеку OpenSSL.

openssl.load_library

синтаксис: name, err = openssl.load_library()

Попробуйте загрузить общие библиотеки OpenSSL. Эта функция пытается несколько известных шаблонов, как может быть названа библиотека, и возвращает имя библиотеки crypto, если она была успешно загружена, и ошибку, если есть.

При выполнении внутри CLI resty или OpenResty с включенным SSL вызов этой функции не требуется.

openssl.load_modules

синтаксис: openssl.load_modules()

Загрузите все доступные подмодули в текущий модуль:

  bn = require("resty.openssl.bn"),
  cipher = require("resty.openssl.cipher"),
  digest = require("resty.openssl.digest"),
  hmac = require("resty.openssl.hmac"),
  kdf = require("resty.openssl.kdf"),
  pkey = require("resty.openssl.pkey"),
  objects = require("resty.openssl.objects"),
  rand = require("resty.openssl.rand"),
  version = require("resty.openssl.version"),
  x509 = require("resty.openssl.x509"),
  altname = require("resty.openssl.x509.altname"),
  chain = require("resty.openssl.x509.chain"),
  csr = require("resty.openssl.x509.csr"),
  crl = require("resty.openssl.x509.crl"),
  extension = require("resty.openssl.x509.extension"),
  extensions = require("resty.openssl.x509.extensions"),
  name = require("resty.openssl.x509.name"),
  store = require("resty.openssl.x509.store"),
  ssl = require("resty.openssl.ssl"),
  ssl_ctx = require("resty.openssl.ssl_ctx"),

Начиная с OpenSSL 3.0, provider и mac ctx также доступны.

openssl.luaossl_compat

синтаксис: openssl.luaossl_compat()

Предоставляет API в стиле luaossl, который использует наименование camelCase; пользователь может ожидать замену без изменений.

Например, pkey:get_parameters сопоставляется с pkey:getParameters.

Обратите внимание, что не все API luaossl были реализованы, пожалуйста, проверьте README для источника правды.

openssl.get_fips_mode

синтаксис: enabled = openssl.get_fips_mode()

Возвращает булево значение, указывающее, включен ли режим FIPS.

openssl.set_fips_mode

синтаксис: ok, err = openssl.set_fips_mode(enabled)

Переключает режим FIPS включен или выключен.

lua-resty-openssl поддерживает следующие режимы:

Серия OpenSSL 1.0.2 с модулем fips 2.0

Компилируйте модуль в соответствии с политикой безопасности,

Поставщик fips OpenSSL 3.0.0

Смотрите https://wiki.openssl.org/index.php/OpenSSL_3.0 Раздел 7 Компилируйте поставщика в соответствии с руководством, установите fipsmodule.cnf, который соответствует хешу поставщика FIPS fips.so.

В OpenSSL 3.0 или более поздних версиях эта функция также включает и выключает свойства по умолчанию для функций EVP. Когда включено, все приложения, использующие API EVP_*, будут перенаправлены на реализации, соответствующие FIPS, и не будут иметь доступа к алгоритмам, не соответствующим FIPS.

Вызов этой функции эквивалентен загрузке поставщика fips и вызову openssl.set_default_properties("fips=yes").

Если поставщик fips загружен, но свойства по умолчанию не установлены, используйте следующее, чтобы явно получить реализацию FIPS.

local provider = require "resty.openssl.provider"
assert(provider.load("fips"))
local cipher = require "resty.openssl.cipher"
local c = assert(cipher.new("aes256"))
print(c:get_provider_name()) -- печатает "default"
local c = assert(cipher.new("aes256", "fips=yes"))
print(c:get_provider_name()) -- печатает "fips"

openssl.get_fips_version_text

синтаксис: text, err = openssl.get_fips_version_text()

Возвращает текст версии модуля FIPS, доступный только в OpenSSL 3.x.

openssl.set_default_properties

синтаксис: ok, err = openssl.set_default_properties(props)

Устанавливает свойства по умолчанию для всех будущих выборок алгоритмов EVP, как неявных, так и явных. См. "ВЫБОР АЛГОРИТМОВ" в crypto(7) для получения информации о неявной и явной выборке.

openssl.list_cipher_algorithms

синтаксис: ret = openssl.list_cipher_algorithms(hide_provider?)

Возвращает доступные алгоритмы шифрования в массиве. Установите hide_provider в true, чтобы скрыть имя поставщика из результата.

openssl.list_digest_algorithms

синтаксис: ret = openssl.list_digest_algorithms(hide_provider?)

Возвращает доступные алгоритмы дайджеста в массиве. Установите hide_provider в true, чтобы скрыть имя поставщика из результата.

openssl.list_mac_algorithms

синтаксис: ret = openssl.list_mac_algorithms(hide_provider?)

Возвращает доступные алгоритмы MAC в массиве. Установите hide_provider в true, чтобы скрыть имя поставщика из результата.

openssl.list_kdf_algorithms

синтаксис: ret = openssl.list_kdf_algorithms(hide_provider?)

Возвращает доступные алгоритмы KDF в массиве. Установите hide_provider в true, чтобы скрыть имя поставщика из результата.

openssl.list_ssl_ciphers

синтаксис: cipher_string, err = openssl.list_ssl_ciphers(cipher_list?, ciphersuites?, protocol?)

Возвращает стандартные SSL шифры в виде строки. cipher_list (до TLSv1.3) и ciphersuites (TLSv1.3) могут использоваться для расширения настроек шифрования, соответствующих protocol.

openssl.list_ssl_ciphers()
openssl.list_ssl_ciphers("ECDHE-ECDSA-AES128-SHA")
openssl.list_ssl_ciphers("ECDHE-ECDSA-AES128-SHA", nil, "TLSv1.2")
openssl.list_ssl_ciphers("ECDHE-ECDSA-AES128-SHA", "TLS_CHACHA20_POLY1305_SHA256", "TLSv1.3")

resty.openssl.ctx

Модуль для предоставления переключений контекста OSSL_LIB_CTX.

OSSL_LIB_CTX — это внутренний тип контекста библиотеки OpenSSL. Приложения могут выделять свои собственные, но также могут использовать NULL, чтобы использовать контекст по умолчанию с функциями, которые принимают аргумент OSSL_LIB_CTX.

Смотрите OSSL_LIB_CTX.3 для более глубокого чтения.

Контекст в настоящее время эффективен для следующих модулей:

Этот модуль доступен только в OpenSSL 3.0 или более поздних версиях.

ctx.new

синтаксис: ok, err = ctx.new(request_context_only?, conf_file?)

Создает новый контекст и использует его как контекст по умолчанию для этого модуля. Когда request_context_only установлен в true, контекст используется только внутри текущего контекста запроса. conf_file может опционально указывать файл конфигурации OpenSSL для создания контекста.

Созданный контекст автоматически освобождается с его заданным жизненным циклом.

-- инициализировать экземпляр шифра AES из данного поставщика реализации только для текущего запроса, не вмешиваясь в другие части кода или будущие запросы, использующие тот же алгоритм.
assert(require("resty.openssl.ctx").new(true))
local p = assert(require("resty.openssl.provider").load("myprovider"))
local c = require("resty.openssl.cipher").new("aes256")
print(c:encrypt(string.rep("0", 32), string.rep("0", 16), "🦢"))
-- не нужно освобождать поставщика и ctx, они автоматически очищаются сборщиком мусора

ctx.free

синтаксис: ctx.free(request_context_only?)

Освобождает контекст, который был ранее создан с помощью ctx.new.

resty.openssl.err

Модуль для предоставления сообщений об ошибках.

err.format_error

синтаксис: msg = err.format_error(ctx_msg?, return_code?, all_errors?)

синтаксис: msg = err.format_all_errors(ctx_msg?, return_code?)

Возвращает последнее сообщение об ошибке из последнего кода ошибки. Ошибки форматируются как:

[ctx_msg]: код: [return_code]: ошибка:[код ошибки]:[имя библиотеки]:[имя функции]:[строка причины]:[имя файла]:[номер строки]:

В OpenSSL до 3.x ошибки форматируются как:

[ctx_msg]: код: [return_code]: [имя файла]:[номер строки]:ошибка:[код ошибки]:[имя библиотеки]:[имя функции]:[строка причины]:

Если all_errors установлен в true, все ошибки, а не только последняя, будут возвращены в одной строке. Все ошибки, выбрасываемые этой библиотекой, внутренне выбрасывают только последнюю ошибку.

Например:

local f = io.open("t/fixtures/ec_key_encrypted.pem"):read("*a")
local privkey, err = require("resty.openssl.pkey").new(f, {
    format = "PEM",
    type = "pr",
    passphrase = "wrongpasswrod",
})
ngx.say(err)
-- pkey.new:load_key: ошибка:4800065:PEM routines:PEM_do_header:неверная расшифровка:crypto/pem/pem_lib.c:467:

err.get_last_error_code

синтаксис: code = err.get_last_error_code()

Возвращает последний код ошибки.

err.get_lib_error_string

синтаксис: lib_error_message = err.get_lib_error_string(code?)

Возвращает имя библиотеки последнего кода ошибки в виде строки. Если code установлен, возвращает имя библиотеки, соответствующее предоставленному коду ошибки.

err.get_reason_error_string

синтаксис: reason_error_message = err.get_reason_error_string(code?)

Возвращает причину последнего кода ошибки в виде строки. Если code установлен, возвращает причину, соответствующую предоставленному коду ошибки.

resty.openssl.version

Модуль для предоставления информации о версии.

resty.openssl.provider

Модуль для взаимодействия с поставщиками. Этот модуль работает только на OpenSSL >= 3.0.0.

provider.load

синтаксис: pro, err = provider.load(name, try?)

Загружает поставщика с name. Если try установлен в true, OpenSSL не отключит запасные поставщики, если поставщик не может быть загружен и инициализирован. Если поставщик загружается успешно, однако, запасные поставщики отключаются.

По умолчанию эта функция загружает поставщика в контекст по умолчанию, что означает, что это повлияет на другие приложения в том же процессе, использующие контекст по умолчанию. Если такое поведение нежелательно, рассмотрите возможность использования ctx для загрузки поставщика только в ограниченной области.

provider.istype

синтаксис: ok = pkey.provider(table)

Возвращает true, если таблица является экземпляром provider. Возвращает false в противном случае.

provider.is_available

синтаксис: ok, err = provider.is_available(name)

Проверяет, доступен ли именованный поставщик для использования.

provider.set_default_search_path

синтаксис: ok, err = provider.set_default_search_path(name)

Указывает путь по умолчанию, который будет использоваться для поиска поставщиков.

provider:unload

синтаксис: ok, err = pro:unload(name)

Разгружает поставщика, который был ранее загружен с помощью provider.load.

provider:self_test

синтаксис: ok, err = pro:self_test(name)

Запускает самопроверку поставщика по запросу. Если самопроверка не проходит, то поставщик не сможет предоставить никаких дальнейших услуг и алгоритмов.

provider:get_params

синтаксис: ok, err = pro:get_params(key1, key2?...)

Возвращает одно или несколько значений параметров поставщика.

local pro = require "resty.openssl.provider"

local p = pro.load("default")

local name = assert(p:get_params("name"))
print(name)
-- выводит "OpenSSL Default Provider"

local result = assert(p:get_params("name", "version", "buildinfo", "status"))
print(require("cjson").encode(result))
-- выводит '{"buildinfo":"3.0.0-alpha7","name":"OpenSSL Default Provider","status":1,"version":"3.0.0"}'

resty.openssl.pkey

Модуль для взаимодействия с закрытыми и открытыми ключами (EVP_PKEY).

Каждый тип ключа может поддерживать только часть операций:

Тип ключа Загрузить существующий ключ Генерация ключа Шифрование/Дешифрование Подпись/Проверка Обмен ключами
RSA Y Y Y Y
DH Y Y Y
EC Y Y Y (ECDSA) Y (ECDH)
Ed25519 Y Y Y (PureEdDSA)
X25519 Y Y Y (ECDH)
Ed448 Y Y Y (PureEdDSA)
X448 Y Y Y (ECDH)

Прямой поддержки шифрования и дешифрования для EC и ECX не существует, но процессы, такие как ECIES, возможны с помощью pkey:derive, kdf и cipher.

pkey.new

Загрузка существующего ключа

синтаксис: pk, err = pkey.new(string, opts?)

Поддерживает загрузку закрытого или открытого ключа в формате PEM, DER или JWK, переданного в качестве первого аргумента string.

Второй параметр opts принимает опциональную таблицу для ограничения поведения загрузки ключа.

  • opts.format: явно установить в "PEM", "DER", "JWK" для загрузки конкретного формата или установить в "*" для автоматического определения
  • opts.type: явно установить в "pr" для закрытого ключа, "pu" для открытого ключа; установить в "*" для автоматического определения

При загрузке PEM-кодированного RSA-ключа он может быть либо закодированным в PKCS#8 SubjectPublicKeyInfo/PrivateKeyInfo, либо закодированным в PKCS#1 RSAPublicKey/RSAPrivateKey.

При загрузке зашифрованного PEM-кодированного ключа passphrase для его расшифровки может быть установлен либо в opts.passphrase, либо в opts.passphrase_cb:

pkey.new(pem_or_der_text, {
  format = "*", -- выбор "PEM", "DER", "JWK" или "*" для автоматического определения
  type = "*", -- выбор "pr" для закрытого ключа, "pu" для открытого ключа и "*" для автоматического определения
  passphrase = "секретный пароль", -- пароль шифрования PEM
  passphrase_cb = function()
    return "секретный пароль"
  end, -- функция обратного вызова пароля шифрования PEM
}

При загрузке JWK есть несколько нюансов: - Убедитесь, что закодированный текст JSON передан, он должен быть декодирован из base64. - При использовании OpenSSL 1.1.1 или lua-resty-openssl ранее 1.6.0 ограничение type на JWK ключ поддерживается только в OpenSSL 3.x и lua-resty-openssl 1.6.0. В противном случае параметры в предоставленном JSON определят, загружается ли закрытый или открытый ключ, указание type приведет к ошибке; также часть открытого ключа для ключей OKP (параметр x) не учитывается и выводится из части закрытого ключа (параметр d), если он указан. - Поддерживаются только типы ключей RSA, P-256, P-384 и P-512 EC, Ed25519, X25519, Ed448 и X448 OKP ключи. - Подписи и проверки должны использовать опцию ecdsa_use_raw, чтобы работать со стандартами JWS для EC ключей. См. pkey:sign и pkey.verify для подробностей. - При запуске вне OpenResty необходимо установить библиотеку JSON (cjson или dkjson) и basexx.

Генерация ключа

синтаксис: pk, err = pkey.new(config?)

Генерирует новый открытый или закрытый ключ.

Для генерации RSA-ключа таблица config может содержать поля bits и exp для управления генерацией ключа. Когда config не указан, эта функция генерирует 2048-битный RSA-ключ с exponent 65537, что эквивалентно:

local key, err = pkey.new({
  type = 'RSA',
  bits = 2048,
  exp = 65537
})

Для генерации EC или DH ключа, пожалуйста, обратитесь к pkey.paramgen для возможных значений таблицы config. Например:

local key, err = pkey.new({
  type = 'EC',
  curve = 'prime256v1',
})

Также возможно передать PEM-кодированные параметры EC или DH в config.param для генерации ключа:

local dhparam = pkey.paramgen({
  type = 'DH',
  group = 'dh_1024_160'
})
-- ИЛИ
-- local dhparam = io.read("dhparams.pem"):read("*a")

local key, err = pkey.new({
  type = 'DH',
  param = dhparam,
})

Также возможно передать необработанные строки управления pkeyopt в таблице config, как используется в CLI программе genpkey. См. openssl-genpkey(1) для списка опций.

Например:

pkey.new({
  type = 'RSA',
  bits = 2048,
  exp = 65537,
})
-- то же самое, что
pkey.new({
  type = 'RSA',
  exp = 65537,
  "rsa_keygen_bits:4096",
})

Композиция ключа

синтаксис: pk, err = pkey.new(config?)

Составляет открытый или закрытый ключ, используя существующие параметры. Чтобы увидеть список параметров для каждого ключа, обратитесь к pkey:set_parameters.

Только type и params должны существовать в таблице config, все другие ключи будут проигнорированы.

local private_bn = require "resty.openssl.bn".new("7F48282CCA4C1A65D589C06DBE9C42AE50FBFFDF3A18CBB48498E1DE47F11BE1A3486CD8FA950D68F111970F922279D8", 16)
local p_384, err = assert(require("resty.openssl.pkey").new({
    type = "EC",
    params = {
        private = private_bn,
        group = "secp384r1",
    }
}))

pkey.istype

синтаксис: ok = pkey.istype(table)

Возвращает true, если таблица является экземпляром pkey. Возвращает false в противном случае.

pkey.paramgen

синтаксис: pem_txt, err = pk.paramgen(config)

Генерирует параметры для EC или DH ключа и выводит в виде PEM-кодированного текста.

Для EC ключа:

Параметр Описание
type "EC"
curve EC кривые. Если опущено, по умолчанию "prime192v1". Чтобы увидеть список поддерживаемых EC кривых, используйте openssl ecparam -list_curves.

Для DH ключа:

Параметр Описание
type "DH"
bits Генерирует новый DH параметр с bits длинным простым числом. Если опущено, по умолчанию 2048. Начиная с OpenSSL 3.0, только биты равные 2048 разрешены.
group Используйте предопределенные группы вместо генерации новой. bit будет проигнорирован, если group установлен.

Возможные значения для group: - RFC7919 "ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", "ffdhe8192" - RFC5114 "dh_1024_160", "dh_2048_224", "dh_2048_256" - RFC3526 "modp_1536", "modp_2048", "modp_3072", "modp_4096", "modp_6144", "modp_8192"

local pem, err = pkey.paramgen({
  type = 'EC',
  curve = 'prime192v1',
})

local pem, err = pkey.paramgen({
  type = 'DH',
  group = 'ffdhe4096',
})

Также возможно передать необработанные строки управления pkeyopt в таблице config, как используется в CLI программе genpkey. См. openssl-genpkey(1) для списка опций.

pkey:get_provider_name

синтаксис: name = pkey:get_provider_name()

Возвращает имя поставщика pkey.

Эта функция доступна с OpenSSL 3.0.

pkey:gettable_params, pkey:settable_params, pkey:get_param, pkey:set_params

Запросите устанавливаемые или получаемые параметры и установите или получите параметры. См. Generic EVP parameter getter/setter.

pkey:get_parameters

синтаксис: parameters, err = pk:get_parameters()

Возвращает таблицу, содержащую parameters экземпляра pkey.

pkey:set_parameters

синтаксис: ok, err = pk:set_parameters(params)

Устанавливает параметры pkey из таблицы params. Если параметр не установлен в таблице params, он остается неизменным в экземпляре pkey.

local pk, err = require("resty.openssl.pkey").new()
local parameters, err = pk:get_parameters()
local e = parameters.e
ngx.say(e:to_number())
-- выводит 65537

local ok, err = pk:set_parameters({
  e = require("resty.openssl.bn").from_hex("100001")
})

local ok, err = pk:set_parameters(parameters)

Параметры для RSA ключа:

Параметр Описание Тип
n модуль, общий для открытого и закрытого ключа bn
e открытая экспонента bn
d закрытая экспонента bn
p первый фактор n bn
q второй фактор n bn
dmp1 d mod (p - 1), exponent1 bn
dmq1 d mod (q - 1), exponent2 bn
iqmp (InverseQ)(q) = 1 mod p, коэффициент bn

Параметры для EC ключа:

Параметр Описание Тип
private закрытый ключ bn
public открытый ключ bn
x x координата открытого ключа bn
y y координата открытого ключа bn
group именованная кривая группа [NID] как число, когда передается в set_parameters(), также можно использовать текстовое представление. Это отличается от luaossl, где возвращается экземпляр EC_GROUP.

Невозможно установить x, y с public одновременно, так как x и y по сути являются другой репрезентацией public. Также в настоящее время возможно установить только x и y одновременно.

Параметры для DH ключа:

Параметр Описание Тип
private закрытый ключ bn
public открытый ключ bn
p простое число bn
q референсная позиция bn
g базовый генератор bn

Параметры для ключей Curve25519 и Curve448:

Параметр Описание Тип
private необработанный закрытый ключ, представленный в виде байтов строка
public необработанный открытый ключ, представленный в виде байтов строка

pkey:is_private

синтаксис: ok = pk:is_private()

Проверяет, является ли pk закрытым ключом. Возвращает true, если это закрытый ключ, возвращает false, если это открытый ключ.

pkey:get_key_type

синтаксис: obj, err = pk:get_key_type(nid_only?)

Возвращает ASN1_OBJECT типа ключа закрытого ключа в виде таблицы.

Начиная с lua-resty-openssl 1.6.0, необязательный аргумент nid_only может быть установлен в true, чтобы вернуть только числовой NID ключа.

local pkey, err = require("resty.openssl.pkey").new({type="X448"})

ngx.say(require("cjson").encode(pkey:get_key_type()))
-- выводит '{"ln":"X448","nid":1035,"sn":"X448","id":"1.3.101.111"}'
ngx.say(pkey:get_key_type(true))
-- выводит 1035

pkey:get_size

синтаксис: size, err = pk:get_size()

Возвращает максимальный подходящий размер для выходных буферов для почти всех операций, которые могут быть выполнены с pkey.

Для RSA ключа это размер модуля. Для EC, Ed25519 и Ed448 ключей это размер закрытого ключа. Для DH ключа это размер простого модуля.

pkey:get_default_digest_type

синтаксис: obj, err = pk:get_default_digest_type()

Возвращает ASN1_OBJECT типа ключа закрытого ключа в виде таблицы. Дополнительное поле mandatory также возвращается в таблице, если mandatory истинно, то другие дайджесты не могут быть использованы.

local pkey, err = require("resty.openssl.pkey").new()

ngx.say(require("cjson").encode(pkey:get_default_digest_type()))
-- выводит '{"ln":"sha256","nid":672,"id":"2.16.840.1.101.3.4.2.1","mandatory":false,"sn":"SHA256"}'

pkey:sign

синтаксис: signature, err = pk:sign(digest)

синтаксис: signature, err = pk:sign(message, md_alg?, padding?, opts?)

Выполняет подпись дайджеста с использованием закрытого ключа, определенного в экземпляре pkey. Первый параметр должен быть экземпляром resty.openssl.digest или строкой. Возвращает подписанный текст и ошибку, если есть.

При передаче экземпляра digest в качестве первого параметра он не должен был вызываться final(), пользователь должен использовать только update(). Этот режим поддерживает только RSA и EC ключи.

При передаче строки в качестве первого параметра параметр md_alg будет указывать имя, которое следует использовать при подписании. Когда md_alg не определен, для RSA и EC ключей эта функция по умолчанию использует SHA256. Для ключей Ed25519 или Ed448 эта функция выполняет подпись PureEdDSA, никакой дайджест сообщения не должен быть указан и не будет использован.

Для RSA ключа также возможно указать схему padding с следующими вариантами:

  pkey.PADDINGS = {
    RSA_PKCS1_PADDING       = 1,
    RSA_SSLV23_PADDING      = 2,
    RSA_NO_PADDING          = 3,
    RSA_PKCS1_OAEP_PADDING  = 4,
    RSA_X931_PADDING        = 5, -- только подпись
    RSA_PKCS1_PSS_PADDING   = 6, -- только подпись и проверка
  }

Когда padding равен RSA_PKCS1_PSS_PADDING, возможно указать длину соли PSS, установив opts.pss_saltlen.

Для EC ключа эта функция выполняет подпись ECDSA. Обратите внимание, что OpenSSL не поддерживает цифровую подпись EC (ECDSA) с устаревшим алгоритмом хеширования MD5 и вернет ошибку при этой комбинации. См. EVP_DigestSign(3) для списка алгоритмов и соответствующих алгоритмов открытого ключа. Обычно подпись ECDSA кодируется в формате ASN.1 DER. Если таблица opts содержит поле ecdsa_use_raw с истинным значением, возвращается двоичное представление, состоящее только из конкатенации двоичного представления pr и ps. Это полезно, например, для отправки подписи как JWS.

opts — это таблица, которая принимает дополнительные параметры с следующими вариантами:

{
  pss_saltlen, -- Для PSS режима только эта опция указывает длину соли.
  mgf1_md, -- Для PSS и OAEP заполнения устанавливает дайджест MGF1. Если дайджест MGF1 не установлен явно в режиме PSS, то используется дайджест подписи.
  oaep_md, -- Дайджест, используемый для хеш-функции OAEP. Если не установлен явно, то используется SHA1.
}

Также возможно передать необработанные строки управления pkeyopt, как используется в CLI программе pkeyutl. Это позволяет пользователю передавать параметры, которые не поддерживаются явно как параметры выше. См. openssl-pkeyutl(1) для списка опций.

pk:sign(message, nil, pk.PADDINGS.RSA_PKCS1_OAEP_PADDING, {
  oaep_md = "sha256",
})
-- то же самое, что и
pk:sign(message, nil, nil, {
  "rsa_padding_mode:oaep",
  "rsa_oaep_md:sha256",
})
-- в pkeyutl CLI вышеуказанное эквивалентно: `openssl pkeyutl -sign -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256

Чтобы подписать сообщение без выполнения дайджеста сообщения, пожалуйста, проверьте pkey:sign_raw.

pkey:verify

синтаксис: ok, err = pk:verify(signature, digest)

синтаксис: ok, err = pk:verify(signature, message, md_alg?, padding?, opts?)

Проверяет подпись (которая может быть строкой, возвращенной pkey:sign). Второй аргумент должен быть экземпляром resty.openssl.digest, который использует тот же алгоритм дайджеста, что и в sign, или строкой. ok возвращает true, если проверка успешна, и false в противном случае. Обратите внимание, что при неудачной проверке err не будет установлен, если используется OpenSSL 1.1.1 или ниже.

При передаче экземпляров digest в качестве второго параметра он не должен был вызываться final(), пользователь должен использовать только update(). Этот режим поддерживает только RSA и EC ключи.

При передаче строки в качестве второго параметра параметр md_alg будет указывать имя, которое следует использовать при проверке. Когда md_alg не определен, для RSA и EC ключей эта функция по умолчанию использует SHA256. Для ключей Ed25519 или Ed448 эта функция выполняет проверку PureEdDSA, никакой дайджест сообщения не должен быть указан и не будет использован.

Когда ключ является RSA ключом, функция принимает необязательный аргумент padding, значения которого такие же, как и в pkey:sign. Когда padding равен RSA_PKCS1_PSS_PADDING, возможно указать длину соли PSS, установив opts.pss_saltlen.

Для EC ключа эта функция выполняет проверку ECDSA. Обычно подпись ECDSA должна быть закодирована в формате ASN.1 DER. Если таблица opts содержит поле ecdsa_use_raw с истинным значением, эта библиотека рассматривает signature как конкатенацию двоичного представления pr и ps. Это полезно, например, для проверки подписи как JWS.

opts — это таблица, которая принимает дополнительные параметры, значения которых такие же, как и в pkey:sign.

-- RSA и EC ключи
local pk, err = require("resty.openssl.pkey").new()
local digest, err = require("resty.openssl.digest").new("SHA256")
digest:update("dog")
-- Неверно:
-- digest:final("dog")
local signature, err = pk:sign(digest)
-- по умолчанию использует SHA256
local signature, err = pk:sign("dog")
ngx.say(ngx.encode_base64(signature))
-- использует SHA256 и PSS заполнение
local signature_pss, err = pk:sign("dog", "sha256", pk.PADDINGS.RSA_PKCS1_PSS_PADDING)

digest, err = require("resty.openssl.digest").new("SHA256")
digest:update("dog")
local ok, err = pk:verify(signature, digest)
-- по умолчанию использует SHA256
local ok, err = pk:verify(signature, "dog")
-- использует SHA256 и PSS заполнение
local ok, err = pk:verify(signature_pss, "dog", "sha256", pk.PADDINGS.RSA_PKCS1_PSS_PADDING)

-- Ed25519 и Ed448 ключи
local pk, err = require("resty.openssl.pkey").new({
  type = "Ed25519",
})
local signature, err = pk:sign("23333")
ngx.say(ngx.encode_base64(signature))

Чтобы проверить сообщение без выполнения дайджеста сообщения, пожалуйста, проверьте pkey:verify_raw и pkey:verify_recover.

pkey:encrypt

синтаксис: cipher_txt, err = pk:encrypt(txt, padding?, opts?)

Шифрует открытый текст txt с помощью экземпляра pkey, который должен загружать открытый ключ.

Необязательный второй аргумент padding имеет то же значение, что и в pkey:sign. Если опущен, padding по умолчанию равен pkey.PADDINGS.RSA_PKCS1_PADDING.

Третий необязательный аргумент opts имеет то же значение, что и в pkey:sign.

pkey:decrypt

синтаксис: txt, err = pk:decrypt(cipher_txt, padding?, opts?)

Дешифрует шифротекст cipher_txt с помощью экземпляра pkey, который должен загружать закрытый ключ.

Необязательный второй аргумент padding имеет то же значение, что и в pkey:sign. Если опущен, padding по умолчанию равен pkey.PADDINGS.RSA_PKCS1_PADDING.

Третий необязательный аргумент opts имеет то же значение, что и в pkey:sign.

local pkey = require("resty.openssl.pkey")
local privkey, err = pkey.new()
local pub_pem = privkey:to_PEM("public")
local pubkey, err = pkey.new(pub_pem)
local s, err = pubkey:encrypt("🦢", pkey.PADDINGS.RSA_PKCS1_PADDING)
ngx.say(#s)
-- выводит 256
local decrypted, err = privkey:decrypt(s)
ngx.say(decrypted)
-- выводит "🦢"

pkey:sign_raw

синтаксис: signature, err = pk:sign_raw(txt, padding?, opts?)

Подписывает шифротекст cipher_txt с помощью экземпляра pkey, который должен загружать закрытый ключ.

Необязательный второй аргумент padding имеет то же значение, что и в pkey:sign. Если опущен, padding по умолчанию равен pkey.PADDINGS.RSA_PKCS1_PADDING.

Третий необязательный аргумент opts имеет то же значение, что и в pkey:sign.

Эта функция также может называться "закрытое шифрование" в некоторых реализациях, таких как NodeJS или PHP. Обратите внимание, что, как предполагают имена функций, эта функция не безопасна для использования в качестве шифрования. При разработке новых приложений пользователю следует использовать pkey:sign для подписания с дайджестом или pkey:encrypt для шифрования.

Смотрите examples/raw-sign-and-recover.lua для примера.

pkey:verify_raw

синтаксис: ok, err = pk:verify_raw(signature, data, md_alg, padding?, opts?)

Проверяет шифротекст signature с сообщением data с помощью экземпляра pkey, который должен загружать открытый ключ. Установите дайджест сообщения в md_alg, но не выполняет дайджест сообщения автоматически, другими словами, эта функция предполагает, что data уже был захеширован с md_alg.

Когда md_alg не определен, для RSA и EC ключей эта функция по умолчанию использует SHA256. Для ключей Ed25519 или Ed448 значение по умолчанию не установлено.

Необязательный четвертый аргумент padding имеет то же значение, что и в pkey:sign. Если опущен, padding по умолчанию равен pkey.PADDINGS.RSA_PKCS1_PADDING.

Пятый необязательный аргумент opts имеет то же значение, что и в pkey:sign.

Смотрите examples/raw-sign-and-recover.lua для примера.

pkey:verify_recover

синтаксис: txt, err = pk:verify_recover(signature, padding?, opts?)

Проверяет шифротекст signature с помощью экземпляра pkey, который должен загружать открытый ключ, и также возвращает оригинальный текст, который был подписан. Эта операция поддерживается только RSA ключом.

Необязательный второй аргумент padding имеет то же значение, что и в pkey:sign. Если опущен, padding по умолчанию равен pkey.PADDINGS.RSA_PKCS1_PADDING.

Третий необязательный аргумент opts имеет то же значение, что и в pkey:sign.

Эта функция также может называться "публичное дешифрование" в некоторых реализациях, таких как NodeJS или PHP.

Смотрите examples/raw-sign-and-recover.lua для примера.

pkey:derive

синтаксис: txt, err = pk:derive(peer_key)

Выводит общий секрет алгоритма открытого ключа peer_key, который должен быть экземпляром pkey.

Смотрите examples/x25519-dh.lua для примера, как работает обмен ключами для ключей X25519 с алгоритмом DH.

pkey:tostring

синтаксис: txt, err = pk:tostring(private_or_public?, fmt?, is_pkcs1?)

Выводит закрытый или открытый ключ экземпляра pkey в PEM-форматированном тексте. Первый аргумент должен быть выбором public, PublicKey, private, PrivateKey или nil.

Второй аргумент fmt может быть PEM, DER, JWK или nil. Если оба аргумента опущены, эта функция возвращает представление PEM открытого ключа.

Если is_pkcs1 установлен в true, вывод кодируется с использованием структуры PKCS#1 RSAPublicKey; кодирование PKCS#1 в настоящее время поддерживается только для RSA ключа в PEM формате. Запись закодированного RSA ключа в формате PKCS#1 в настоящее время не поддерживается при использовании с OpenSSL 3.0.

pkey:to_PEM

синтаксис: pem, err = pk:to_PEM(private_or_public?, is_pkcs1?)

Эквивалентно pkey:tostring(private_or_public, "PEM", is_pkcs1).

resty.openssl.bn

Модуль для экспонирования структуры BIGNUM. Обратите внимание, что bignum — это большое целое число, операции с плавающей запятой (например, квадратный корень) не поддерживаются.

bn.new

синтаксис: b, err = bn.new(number?)

синтаксис: b, err = bn.new(string?, base?)

Создает экземпляр bn. Первый аргумент может быть:

  • nil, чтобы создать пустой экземпляр bn.
  • Число Lua для инициализации экземпляра bn.
  • Строка для инициализации экземпляра bn. Второй аргумент base указывает основание строки и может принимать значения (совместимые с Ruby OpenSSL.BN API):
  • 10 или опущен, для десятичной строки ("23333")
  • 16, для шестнадцатеричной закодированной строки ("5b25")
  • 2, для двоичной строки ("\x5b\x25")
  • 0, для строки формата MPI ("\x00\x00\x00\x02\x5b\x25")

MPI — это формат, который состоит из длины числа в байтах, представленного в виде 4-байтового числа в порядке старшего байта, и самого числа в формате старшего байта, где старший значащий бит сигнализирует о негативном числе (представление чисел с установленным MSB префиксируется нулевым байтом).

bn.dup

синтаксис: b, err = bn.dup(bn_ptr_cdata)

Дублирует BIGNUM*, чтобы создать новый экземпляр bn.

bn.istype

синтаксис: ok = bn.istype(table)

Возвращает true, если таблица является экземпляром bn. Возвращает false в противном случае.

bn.set

синтаксис: b, err = bn:set(number)

синтаксис: b, err = bn:set(string, base?)

Повторно использует существующий экземпляр bn и сбрасывает его значение с заданным числом или строкой. См. bn.new для поддерживаемых типов аргументов.

bn.from_binary, bn:to_binary

синтаксис: bn, err = bn.from_binary(bin)

синтаксис: bin, err = bn:to_binary(padto?)

Создает экземпляр bn из двоичной строки.

Экспортирует значение BIGNUM в двоичной строке.

bn:to_binary принимает необязательный числовой аргумент padto, который может быть использован для дополнения ведущих нулей к выходу до определенной длины.

local to_hex = require "resty.string".to_hex
local b, err = require("resty.openssl.bn").from_binary("\x5b\x25")
local bin, err = b:to_binary()
ngx.say(to_hex(bin))
-- выводит "5b25"

bn.from_mpi, bn:to_mpi

синтаксис: bn, err = bn.from_mpi(bin)

синтаксис: bin, err = bn:to_mpi()

Создает экземпляр bn из двоичной строки формата MPI.

Экспортирует значение BIGNUM в двоичной строке формата MPI.

local to_hex = require "resty.string".to_hex
local b, err = require("resty.openssl.bn").from_mpi("\x00\x00\x00\x02\x5b\x25")
local bin, err = b:to_mpi()
ngx.say(to_hex(bin))
-- выводит "000000025b25"

bn.from_hex, bn:to_hex

синтаксис: bn, err = bn.from_hex(hex)

синтаксис: hex, err = bn:to_hex()

Создает экземпляр bn из шестнадцатерично закодированной строки. Обратите внимание, что ведущий 0x не должен быть включен. Ведущий - указывающий знак может быть включен.

Экспортирует экземпляр bn в шестнадцатерично закодированную строку.

local bn = require("resty.openssl.bn")
local b = bn.from_hex("5B25")
local hex, err = b:to_hex()
ngx.say(hex)
-- выводит "5B25"

bn.from_dec, bn:to_dec

синтаксис: bn, err = bn.from_dec(dec)

синтаксис: dec, err = bn:to_dec()

Создает экземпляр bn из десятичной строки. Ведущий - указывающий знак может быть включен.

Экспортирует экземпляр bn в десятичную строку.

local bn = require("resty.openssl.bn")
local b = bn.from_dec("23333")
local dec, err = b:to_dec()
ngx.say(dec)
-- выводит "23333"

bn:to_number

синтаксис: n, err = bn:to_number()

синтаксис: n, err = bn:tonumber()

Экспортирует младшие 32 бита или 64 бита (в зависимости от ABI) экземпляра bn в число. Это полезно, когда пользователю нужно выполнять побитовые операции.

local bn = require("resty.openssl.bn")
local b = bn.from_dec("23333")
local n, err = b:to_number()
ngx.say(n)
-- выводит 23333
ngx.say(type(n))
-- выводит "number"

bn.generate_prime

синтаксис: bn, err = bn.generate_prime(bits, safe)

Генерирует псевдослучайное простое число длиной в битах bits.

Если safe истинно, это будет безопасное простое число (т.е. простое p, так что (p-1)/2 также является простым).

PRNG должен быть инициализирован перед вызовом BN_generate_prime_ex(). Генерация простого числа имеет незначительную вероятность ошибки.

bn:__metamethods

Различные математические операции могут выполняться так, как будто это число.

local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(222)
 -- следующее возвращает bn
local r
r = -a
r = a + b
r = a - b
r = a * b
r = a / b -- равен bn:idiv, возвращает целочисленное деление
r = a % b
-- все операции могут выполняться между числом и bignum
r = a + 222
r = 222 + a
-- следующее возвращает bool
local bool
bool = a < b
bool = a >= b
-- сравнение между числами не будет работать
-- Неверно: bool = a < 222

bn:add, bn:sub, bn:mul, bn:div, bn:exp, bn:mod, bn:gcd

синтаксис: r = a:op(b)

синтаксис: r = bn.op(a, b)

Выполняет математические операции op.

  • add: сложение
  • sub: вычитание
  • mul: умножение
  • div, idiv: целочисленное деление (деление с округлением вниз до ближайшего целого)
  • exp, pow: b-я степень a, эта функция быстрее, чем повторное a * a * ....
  • mod: модуль
  • gcd: наибольший общий делитель a и b.

Обратите внимание, что add, sub, mul, div, mod также доступны с операторами +, -, *, /, %. См. вышеуказанный раздел для примеров.

local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(9876)
local r
-- следующее равно
r = a:add(b)
r = bn.add(a, b)
r = a:add(9876)
r = bn.add(a, 9876)
r = bn.add(123456, b)
r = bn.add(123456, 9876)

bn:sqr

синтаксис: r = a:sqr()

синтаксис: r = bn.sqr(a)

Вычисляет 2-ю степень a. Эта функция быстрее, чем r = a * a.

bn:mod_add, bn:mod_sub, bn:mod_mul, bn:mod_exp

синтаксис: r = a:op(b, m)

синтаксис: r = bn.op(a, b, m)

Выполняет модульные математические операции op.

  • mod_add: добавляет a к b по модулю m
  • mod_sub: вычитает b из a по модулю m
  • mod_mul: умножает a на b и находит неотрицательный остаток относительно модуля m
  • mod_exp, mod_pow: вычисляет a в степени b по модулю m (r=a^b % m). Эта функция использует меньше времени и места, чем exp. Не вызывайте эту функцию, когда m четное и любой из параметров имеет флаг BN_FLG_CONSTTIME, установленный.
local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(9876)
local r
-- следующее равно
r = a:mod_add(b, 3)
r = bn.mod_add(a, b, 3)
r = a:mod_add(9876, 3)
r = bn.mod_add(a, 9876, 3)
r = bn.mod_add(123456, b, 3)
r = bn.mod_add(123456, 9876, 3)

bn:mod_sqr

синтаксис: r = a:mod_sqr(m)

синтаксис: r = bn.mod_sqr(a, m)

Возвращает квадрат a по модулю m.

bn:lshift, bn:rshift

синтаксис: r = bn:lshift(bit)

синтаксис: r = bn.lshift(a, bit)

синтаксис: r = bn:rshift(bit)

синтаксис: r = bn.rshift(a, bit)

Сдвиг битов a на bit бит.

bn:is_zero, bn:is_one, bn:is_odd, bn:is_word

синтаксис: ok = bn:is_zero()

синтаксис: ok = bn:is_one()

синтаксис: ok = bn:is_odd()

синтаксис: ok, err = bn:is_word(n)

Проверяет, является ли bn 0, 1, нечетным числом или числом n соответственно.

bn:is_prime

синтаксис: ok, err = bn:is_prime(nchecks?)

Проверяет, является ли bn простым числом. Возвращает true, если это простое число с вероятностью ошибки менее 0.25^nchecks и ошибку, если есть. Если опущено, nchecks устанавливается в 0, что означает выбор числа итераций в зависимости от размера числа.

Эта функция выполняет вероятностный тест на простоту Миллера-Рабина с nchecks итерациями. Если nchecks == BN_prime_checks (0), используется количество итераций, которое дает уровень ложноположительных результатов не более 2^-64 для случайного ввода. Уровень ошибок зависит от размера простого числа и уменьшается для больших простых чисел. Уровень составляет 2^-80 начиная с 308 бит, 2^-112 на 852 битах, 2^-128 на 1080 битах, 2^-192 на 3747 битах и 2^-256 на 6394 битах.

Когда источник простого числа не является случайным или ненадежным, количество проверок должно быть значительно выше, чтобы достичь того же уровня уверенности: оно должно равняться половине целевого уровня безопасности в битах (округлено до следующего целого числа, если необходимо). Например, чтобы достичь уровня безопасности в 128 бит, nchecks следует установить в 64.

Смотрите также BN_is_prime(3).

resty.openssl.cipher

Модуль для взаимодействия с симметричной криптографией (EVP_CIPHER).

cipher.new

синтаксис: d, err = cipher.new(cipher_name, properties?)

Создает экземпляр шифра. cipher_name — это нечувствительная к регистру строка имени алгоритма шифрования. Чтобы просмотреть список реализованных алгоритмов шифрования, используйте openssl.list_cipher_algorithms или openssl list -cipher-algorithms.

Начиная с OpenSSL 3.0, эта функция принимает необязательный параметр properties, чтобы явно выбрать поставщика для получения алгоритмов.

cipher.istype

синтаксис: ok = cipher.istype(table)

Возвращает true, если таблица является экземпляром cipher. Возвращает false в противном случае.

cipher.set_buffer_size

синтаксис: ok = cipher.set_buffer_size(sz)

Изменяет размер внутреннего буфера, используемого всеми экземплярами шифра. Размер буфера по умолчанию составляет 1024 байта.

Если вы ожидаете передать текст ввода размером более 1024 байт за один раз в update(), encrypt() или decrypt(), установка буфера на размер, превышающий ожидаемый размер ввода, улучшит производительность, позволяя большему количеству кода быть JIT-ируемым.

Избегайте вызова этой функции в горячем пути, так как это перераспределяет буфер каждый раз, когда она вызывается.

cipher:get_provider_name

синтаксис: name = cipher:get_provider_name()

Возвращает имя поставщика cipher.

Эта функция доступна с OpenSSL 3.0.

cipher:gettable_params, cipher:settable_params, cipher:get_param, cipher:set_params

Запросите устанавливаемые или получаемые параметры и установите или получите параметры. См. Generic EVP parameter getter/setter.

cipher:encrypt

синтаксис: s, err = cipher:encrypt(key, iv?, s, no_padding?, aead_aad?)

Шифрует текст s с ключом key и IV iv. Возвращает зашифрованный текст в виде необработанной двоичной строки и ошибку, если есть. Опционально принимает булевый no_padding, который указывает шифру, включить или отключить заполнение, по умолчанию false (включить заполнение). Если no_padding равен true, длина s должна быть кратной размеру блока, иначе произойдет ошибка.

При использовании режима GCM или CCM или шифра chacha20-poly1305 также возможно передать Дополнительные Аутентифицированные Данные (AAD) в качестве пятого аргумента.

Эта функция является сокращенной версией cipher:init, cipher:set_aead_aad (если применимо), затем cipher:final.

cipher:decrypt

синтаксис: s, err = cipher:decrypt(key, iv?, s, no_padding?, aead_aad?, aead_tag?)

Дешифрует текст s с ключом key и IV iv. Возвращает расшифрованный текст в виде необработанной двоичной строки и ошибку, если есть. Опционально принимает булевый no_padding, который указывает шифру, включить или отключить заполнение, по умолчанию false (включить заполнение). Если no_padding равен true, длина s должна быть кратной размеру блока, иначе произойдет ошибка; также заполнение в расшифрованном тексте не будет удалено.

При использовании режима GCM или CCM или шифра chacha20-poly1305 также возможно передать Дополнительные Аутентифицированные Данные (AAD) в качестве пятого аргумента и тег аутентификации в качестве шестого аргумента.

Эта функция является сокращенной версией cipher:init, cipher:set_aead_aad (если применимо), cipher:set_aead_tag (если применимо), затем cipher:final.

cipher:init

синтаксис: ok, err = cipher:init(key, iv?, opts?)

Инициализирует шифр с ключом key и IV iv. Необязательный третий аргумент — это таблица, состоящая из:

{
    is_encrypt = false,
    no_padding = false,
}

Вызов функции необходим перед cipher:update и cipher:final, если шифр еще не был инициализирован. Но не для cipher:encrypt и cipher:decrypt.

Если вы хотите повторно использовать экземпляр cipher несколько раз, вызов этой функции необходим для очистки внутреннего состояния шифра. Сокращенные функции cipher:encrypt и cipher:decrypt уже заботятся о инициализации и сбросе.

cipher:update

синтаксис: s, err = cipher:update(partial, ...)

Обновляет шифр с одной или несколькими строками. Если шифр имеет больше данных, чем размер блока, чтобы сбросить, функция вернет непустую строку в качестве первого аргумента. Эта функция может использоваться в потоковом режиме для шифрования или дешифрования непрерывного потока данных.

cipher:update_aead_aad

синтаксис: ok, err = cipher:update_aead_aad(aad)

Предоставляет данные AAD шифру, эту функцию можно вызывать более одного раза.

cipher:get_aead_tag

синтаксис: tag, err = cipher:get_aead_tag(size?)

Получает тег аутентификации из шифра с длиной, указанной как size. Если опущен, возвращается тег длиной в половину размера блока. Размер не может превышать размер блока.

Эту функцию можно вызывать только после завершения шифрования.

cipher:set_aead_tag

синтаксис: ok, err = cipher:set_aead_tag(tag)

Устанавливает тег аутентификации шифра с tag.

Эту функцию можно вызывать только до начала дешифрования.

cipher:final

синтаксис: s, err = cipher:final(partial?)

Возвращает зашифрованный или расшифрованный текст в необработанной двоичной строке, опционально принимает одну строку для шифрования или дешифрования.

-- шифрование
local c, err = require("resty.openssl.cipher").new("aes256")
c:init(string.rep("0", 32), string.rep("0", 16), {
    is_encrypt = true,
})
c:update("🦢")
local cipher, err = c:final()
ngx.say(ngx.encode_base64(cipher))
-- выводит "vGJRHufPYrbbnYYC0+BnwQ=="
-- ИЛИ:
local c, err = require("resty.openssl.cipher").new("aes256")
local cipher, err = c:encrypt(string.rep("0", 32), string.rep("0", 16), "🦢")
ngx.say(ngx.encode_base64(cipher))
-- выводит "vGJRHufPYrbbnYYC0+BnwQ=="

-- дешифрование
local encrypted = ngx.decode_base64("vGJRHufPYrbbnYYC0+BnwQ==")
local c, err = require("resty.openssl.cipher").new("aes256")
c:init(string.rep("0", 32), string.rep("0", 16), {
    is_encrypt = false,
})
c:update(encrypted)
local cipher, err = c:final()
ngx.say(cipher)
-- выводит "🦢"
-- ИЛИ:
local c, err = require("resty.openssl.cipher").new("aes256")
local cipher, err = c:decrypt(string.rep("0", 32), string.rep("0", 16), encrypted)
ngx.say(cipher)
-- выводит "🦢"

Примечание: в некоторых реализациях, таких как libsodium или Java, AEAD шифры добавляют tag (или MAC) в конец зашифрованного шифротекста. В таком случае пользователю необходимо вручную отрезать tag правильного размера (обычно 16 байт) и передать шифротекст и tag отдельно.

Смотрите examples/aes-gcm-aead.lua для примера использования AEAD режимов с аутентификацией.

cipher:derive

синтаксис: key, iv, err = cipher:derive(key, salt?, count?, md?)

Выводит ключ и IV (если применимо) из данного материала, которые могут быть использованы в текущем шифре. Эта функция полезна в основном для работы с ключами, которые уже были выведены из того же алгоритма.