Aller au contenu

openssl

# *openssl*: Liaison OpenSSL basée sur FFI pour nginx-module-lua

## Installation

Si vous n'avez pas configuré l'abonnement au dépôt RPM, [inscrivez-vous](https://www.getpagespeed.com/repo-subscribe). Ensuite, vous pouvez procéder avec les étapes suivantes.

### CentOS/RHEL 7 ou Amazon Linux 2

```bash
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

Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.

Ce document décrit lua-resty-openssl v1.7.1 publié le 13 janvier 2026.


Liaison OpenSSL basée sur FFI pour LuaJIT, prenant en charge OpenSSL 3.x, série 1.1.

Le support d'OpenSSL 1.1.0, 1.0.2 et BoringSSL a été abandonné, mais est toujours disponible dans la branche 0.x.

Statut de construction luarocks opm

Description

lua-resty-openssl est une bibliothèque de liaison OpenSSL basée sur FFI, prenant actuellement en charge OpenSSL 3.x et la série 1.1.1.

Synopsis

Cette bibliothèque est fortement inspirée par luaossl, tout en utilisant une convention de nommage plus proche de l'API OpenSSL originale. Par exemple, une fonction appelée X509_set_pubkey dans l'API C d'OpenSSL s'attendra à exister sous la forme resty.openssl.x509:set_pubkey. Les CamelCase sont remplacés par des underscore_case, par exemple X509_set_serialNumber devient resty.openssl.x509:set_serial_number. Une autre différence par rapport à luaossl est que les erreurs ne sont jamais lancées en utilisant error(), mais sont plutôt retournées comme dernier paramètre.

Chaque table Lua retournée par new() contient un objet cdata ctx. Les utilisateurs ne sont pas censés définir manuellement ffi.gc ou appeler le destructeur correspondant de la structure ctx (comme les fonctions *_free).

resty.openssl

Ce module méta fournit une vérification de version de la bibliothèque OpenSSL liée.

openssl.load_library

syntax: name, err = openssl.load_library()

Essaye de charger les bibliothèques partagées OpenSSL. Cette fonction essaie quelques motifs connus que la bibliothèque pourrait avoir et retourne le nom de la bibliothèque crypto si elle est chargée avec succès et une erreur le cas échéant.

Lors de l'exécution dans resty CLI ou OpenResty avec SSL activé, appeler cette fonction n'est pas nécessaire.

openssl.load_modules

syntax: openssl.load_modules()

Charge tous les sous-modules disponibles dans le module actuel :

  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"),

À partir d'OpenSSL 3.0, provider et mac ctx sont également disponibles.

openssl.luaossl_compat

syntax: openssl.luaossl_compat()

Fournit une API de type luaossl qui utilise une convention de nommage camelCase ; l'utilisateur peut s'attendre à un remplacement direct.

Par exemple, pkey:get_parameters est mappé à pkey:getParameters.

Notez que toutes les API luaossl n'ont pas été mises en œuvre, veuillez consulter le README pour la source de vérité.

openssl.get_fips_mode

syntax: enabled = openssl.get_fips_mode()

Retourne un booléen indiquant si le mode FIPS est activé.

openssl.set_fips_mode

syntax: ok, err = openssl.set_fips_mode(enabled)

Bascule le mode FIPS activé ou désactivé.

lua-resty-openssl prend en charge les modes suivants :

Série OpenSSL 1.0.2 avec module fips 2.0

Compiler le module selon la politique de sécurité,

Fournisseur fips d'OpenSSL 3.0.0

Se référer à https://wiki.openssl.org/index.php/OpenSSL_3.0 Section 7 Compiler le fournisseur selon le guide, installer le fichier fipsmodule.cnf qui correspond au hachage du fournisseur fips.so.

Sur OpenSSL 3.0 ou ultérieur, cette fonction active et désactive également les propriétés par défaut pour les fonctions EVP. Lorsqu'il est activé, toutes les applications utilisant l'API EVP_* seront redirigées vers des implémentations conformes à FIPS et n'auront pas accès aux algorithmes non conformes à FIPS.

Appeler cette fonction équivaut à charger le fournisseur fips et à appeler openssl.set_default_properties("fips=yes").

Si le fournisseur fips est chargé mais que les propriétés par défaut ne sont pas définies, utilisez ce qui suit pour récupérer explicitement l'implémentation 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()) -- affiche "default"
local c = assert(cipher.new("aes256", "fips=yes"))
print(c:get_provider_name()) -- affiche "fips"

openssl.get_fips_version_text

syntax: text, err = openssl.get_fips_version_text()

Retourne le texte de version du module FIPS, disponible uniquement sur OpenSSL 3.x.

openssl.set_default_properties

syntax: ok, err = openssl.set_default_properties(props)

Définit les propriétés par défaut pour tous les futurs fetchs d'algorithmes EVP, implicites ainsi qu'explicites. Voir "ALGORITHM FETCHING" dans crypto(7) pour des informations sur le fetch implicite et explicite.

openssl.list_cipher_algorithms

syntax: ret = openssl.list_cipher_algorithms(hide_provider?)

Retourne les algorithmes de chiffrement disponibles dans un tableau. Définissez hide_provider sur true pour cacher le nom du fournisseur du résultat.

openssl.list_digest_algorithms

syntax: ret = openssl.list_digest_algorithms(hide_provider?)

Retourne les algorithmes de hachage disponibles dans un tableau. Définissez hide_provider sur true pour cacher le nom du fournisseur du résultat.

openssl.list_mac_algorithms

syntax: ret = openssl.list_mac_algorithms(hide_provider?)

Retourne les algorithmes MAC disponibles dans un tableau. Définissez hide_provider sur true pour cacher le nom du fournisseur du résultat.

openssl.list_kdf_algorithms

syntax: ret = openssl.list_kdf_algorithms(hide_provider?)

Retourne les algorithmes KDF disponibles dans un tableau. Définissez hide_provider sur true pour cacher le nom du fournisseur du résultat.

openssl.list_ssl_ciphers

syntax: cipher_string, err = openssl.list_ssl_ciphers(cipher_list?, ciphersuites?, protocol?)

Retourne les ciphers SSL par défaut sous forme de chaîne. cipher_list (avant TLSv1.3) et ciphersuites (TLSv1.3) peuvent être utilisés pour étendre les paramètres de chiffrement correspondant au 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

Un module pour fournir des commutations de contexte OSSL_LIB_CTX.

OSSL_LIB_CTX est un type de contexte de bibliothèque OpenSSL interne. Les applications peuvent allouer le leur, mais peuvent également utiliser NULL pour utiliser un contexte par défaut avec les fonctions qui prennent un argument OSSL_LIB_CTX.

Voir OSSL_LIB_CTX.3 pour une lecture plus approfondie.

Le contexte est actuellement efficace pour les modules suivants :

Ce module n'est disponible que sur OpenSSL 3.0 ou ultérieur.

ctx.new

syntax: ok, err = ctx.new(request_context_only?, conf_file?)

Crée un nouveau contexte et l'utilise comme contexte par défaut pour ce module. Lorsque request_context_only est défini sur true, le contexte est uniquement utilisé dans le contexte de la requête actuelle. conf_file peut éventuellement spécifier un fichier de configuration OpenSSL pour créer le contexte.

Le contexte créé est automatiquement libéré avec son cycle de vie donné.

-- initialise une instance de chiffrement AES à partir de l'implémentation du fournisseur donné uniquement
-- pour la requête actuelle, sans interférer avec d'autres parties du code
-- ou futures requêtes utilisant le même algorithme.
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), "🦢"))
-- pas besoin de libérer le fournisseur et ctx, ils sont automatiquement gérés par le GC

ctx.free

syntax: ctx.free(request_context_only?)

Libère le contexte qui a été précédemment créé par ctx.new.

resty.openssl.err

Un module pour fournir des messages d'erreur.

err.format_error

syntax: msg = err.format_error(ctx_msg?, return_code?, all_errors?)

syntax: msg = err.format_all_errors(ctx_msg?, return_code?)

Retourne le dernier message d'erreur du dernier code d'erreur. Les erreurs sont formatées comme suit :

[ctx_msg]: code: [return_code]: error:[error code]:[library name]:[func name]:[reason string]:[file name]:[line number]:

Sur OpenSSL avant 3.x, les erreurs sont formatées comme suit :

[ctx_msg]: code: [return_code]: [file name]:[line number]:error:[error code]:[library name]:[func name]:[reason string]:

Si all_errors est défini sur true, toutes les erreurs, pas seulement la dernière, seront retournées dans une seule chaîne. Toutes les erreurs lancées par cette bibliothèque en interne ne lancent que la dernière erreur.

Par exemple :

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: error:4800065:PEM routines:PEM_do_header:bad decrypt:crypto/pem/pem_lib.c:467:

err.get_last_error_code

syntax: code = err.get_last_error_code()

Retourne le dernier code d'erreur.

err.get_lib_error_string

syntax: lib_error_message = err.get_lib_error_string(code?)

Retourne le nom de la bibliothèque du dernier code d'erreur sous forme de chaîne. Si code est défini, retourne le nom de la bibliothèque correspondant au code d'erreur fourni à la place.

err.get_reason_error_string

syntax: reason_error_message = err.get_reason_error_string(code?)

Retourne la raison du dernier code d'erreur sous forme de chaîne. Si code est défini, retourne la raison correspondant au code d'erreur fourni à la place.

resty.openssl.version

Un module pour fournir des informations sur la version.

resty.openssl.provider

Module pour interagir avec les fournisseurs. Ce module ne fonctionne que sur OpenSSL >= 3.0.0.

provider.load

syntax: pro, err = provider.load(name, try?)

Charge le fournisseur avec name. Si try est défini sur true, OpenSSL ne désactivera pas les fournisseurs de secours si le fournisseur ne peut pas être chargé et initialisé. Si le fournisseur se charge avec succès, cependant, les fournisseurs de secours sont désactivés.

Par défaut, cette fonction charge le fournisseur dans le contexte par défaut, ce qui signifie qu'il affectera d'autres applications dans le même processus utilisant le contexte par défaut également. Si un tel comportement n'est pas souhaité, envisagez d'utiliser ctx pour charger le fournisseur uniquement dans une portée limitée.

provider.istype

syntax: ok = pkey.provider(table)

Retourne true si la table est une instance de provider. Retourne false sinon.

provider.is_available

syntax: ok, err = provider.is_available(name)

Vérifie si un fournisseur nommé est disponible pour utilisation.

provider.set_default_search_path

syntax: ok, err = provider.set_default_search_path(name)

Spécifie le chemin de recherche par défaut qui doit être utilisé pour rechercher des fournisseurs.

provider:unload

syntax: ok, err = pro:unload(name)

Décharge un fournisseur qui a été précédemment chargé par provider.load.

provider:self_test

syntax: ok, err = pro:self_test(name)

Exécute les tests de validation d'un fournisseur à la demande. Si les tests de validation échouent, le fournisseur ne pourra plus fournir d'autres services et algorithmes.

provider:get_params

syntax: ok, err = pro:get_params(key1, key2?...)

Retourne une ou plusieurs valeurs de paramètres du fournisseur.

local pro = require "resty.openssl.provider"

local p = pro.load("default")

local name = assert(p:get_params("name"))
print(name)
-- affiche "OpenSSL Default Provider"

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

resty.openssl.pkey

Module pour interagir avec les clés privées et publiques (EVP_PKEY).

Chaque type de clé peut ne prendre en charge qu'une partie des opérations :

Type de clé Charger une clé existante Génération de clé Chiffrer/Déchiffrer Signer/Vérifier Échange de clé
RSA OUI OUI OUI OUI
DH OUI OUI OUI
EC OUI OUI OUI (ECDSA) OUI (ECDH)
Ed25519 OUI OUI OUI (PureEdDSA)
X25519 OUI OUI OUI (ECDH)
Ed448 OUI OUI OUI (PureEdDSA)
X448 OUI OUI OUI (ECDH)

Le support direct du chiffrement et du déchiffrement pour EC et ECX n'existe pas, mais des processus comme ECIES sont possibles avec pkey:derive, kdf et cipher

pkey.new

Charger une clé existante

syntax: pk, err = pkey.new(string, opts?)

Prend en charge le chargement d'une clé privée ou publique au format PEM, DER ou JWK passé comme premier argument string.

Le deuxième paramètre opts accepte une table optionnelle pour contraindre le comportement du chargement de clé.

  • opts.format: défini explicitement sur "PEM", "DER", "JWK" pour charger un format spécifique ou défini sur "*" pour la détection automatique
  • opts.type: défini explicitement sur "pr" pour la clé privée, "pu" pour la clé publique ; défini sur "*" pour la détection automatique

Lors du chargement d'une clé RSA encodée en PEM, cela peut être soit un SubjectPublicKeyInfo/PrivateKeyInfo encodé PKCS#8, soit un RSAPublicKey/RSAPrivateKey encodé PKCS#1.

Lors du chargement d'une clé PEM encodée chiffrée, la passphrase pour la déchiffrer peut être définie soit dans opts.passphrase, soit dans opts.passphrase_cb :

pkey.new(pem_or_der_text, {
  format = "*", -- choix de "PEM", "DER", "JWK" ou "*" pour la détection automatique
  type = "*", -- choix de "pr" pour la clé privée, "pu" pour la clé publique et "*" pour la détection automatique
  passphrase = "secret password", -- la passphrase de chiffrement PEM
  passphrase_cb = function()
    return "secret password"
  end, -- la fonction de rappel de passphrase de chiffrement PEM
}

Lors du chargement de JWK, il y a quelques mises en garde : - Assurez-vous que le texte JSON encodé est passé, il doit avoir été décodé en base64. - Lors de l'utilisation d'OpenSSL 1.1.1 ou de lua-resty-openssl antérieur à 1.6.0, la contrainte type sur la clé JWK n'est prise en charge que sur OpenSSL 3.x et lua-resty-openssl 1.6.0. Sinon, les paramètres dans le JSON fourni décideront si une clé privée ou publique est chargée, spécifier type entraînera une erreur ; de plus, la partie clé publique pour les clés OKP (le paramètre x) n'est pas honorée et dérivée de la partie clé privée (le paramètre d) si elle est spécifiée. - Seuls les types de clé RSA, P-256, P-384 et P-512 EC, Ed25519, X25519, Ed448 et X448 OKP sont pris en charge. - Les signatures et vérifications doivent utiliser l'option ecdsa_use_raw pour fonctionner avec les normes JWS pour les clés EC. Voir pkey:sign et pkey.verify pour plus de détails. - Lors de l'exécution en dehors d'OpenResty, il est nécessaire d'installer une bibliothèque JSON (cjson ou dkjson) et basexx.

Génération de clé

syntax: pk, err = pkey.new(config?)

Génère une nouvelle clé publique ou clé privée.

Pour générer une clé RSA, la table config peut avoir les champs bits et exp pour contrôler la génération de clé. Lorsque config est émis, cette fonction génère une clé RSA de 2048 bits avec un exponent de 65537, ce qui équivaut à :

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

Pour générer une clé EC ou DH, veuillez vous référer à pkey.paramgen pour les valeurs possibles de la table config. Par exemple :

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

Il est également possible de passer des paramètres EC ou DH encodés en PEM à config.param pour la génération de clé :

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

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

Il est également possible de passer des chaînes de contrôle pkeyopt brutes dans la table config comme utilisé dans le programme CLI genpkey. Voir openssl-genpkey(1) pour une liste d'options.

Par exemple :

pkey.new({
  type = 'RSA',
  bits = 2048,
  exp = 65537,
})
-- est identique à
pkey.new({
  type = 'RSA',
  exp = 65537,
  "rsa_keygen_bits:4096",
})

Composition de clé

syntax: pk, err = pkey.new(config?)

Compose une clé publique ou privée en utilisant des paramètres existants. Pour voir la liste des paramètres pour chaque clé, référez-vous à pkey:set_parameters.

Seuls type et params doivent exister dans la table config, toutes les autres clés seront ignorées.

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

syntax: ok = pkey.istype(table)

Retourne true si la table est une instance de pkey. Retourne false sinon.

pkey.paramgen

syntax: pem_txt, err = pk.paramgen(config)

Génère des paramètres pour une clé EC ou DH et les renvoie sous forme de texte encodé en PEM.

Pour une clé EC :

Paramètre Description
type "EC"
curve Courbes EC. Si omis, par défaut "prime192v1". Pour voir la liste des courbes EC prises en charge, utilisez openssl ecparam -list_curves.

Pour une clé DH :

Paramètre Description
type "DH"
bits Génère un nouveau paramètre DH avec un premier ministre de bits de long. Si omis, par défaut 2048. À partir d'OpenSSL 3.0, seuls les bits égaux à 2048 sont autorisés.
group Utilisez des groupes prédéfinis au lieu d'en générer un nouveau. bit sera ignoré si group est défini.

Les valeurs possibles pour group sont : - 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',
})

Il est également possible de passer des chaînes de contrôle pkeyopt brutes dans la table config comme utilisé dans le programme CLI genpkey. Voir openssl-genpkey(1) pour une liste d'options.

pkey:get_provider_name

syntax: name = pkey:get_provider_name()

Retourne le nom du fournisseur de pkey.

Cette fonction est disponible depuis OpenSSL 3.0.

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

Interroger les paramètres réglables ou récupérables et définir ou obtenir des paramètres. Voir Generic EVP parameter getter/setter.

pkey:get_parameters

syntax: parameters, err = pk:get_parameters()

Retourne une table contenant les parameters de l'instance pkey.

pkey:set_parameters

syntax: ok, err = pk:set_parameters(params)

Définit les paramètres de la pkey à partir d'une table params. Si le paramètre n'est pas défini dans la table params, il reste inchangé dans l'instance pkey.

local pk, err = require("resty.openssl.pkey").new()
local parameters, err = pk:get_parameters()
local e = parameters.e
ngx.say(e:to_number())
-- affiche 65537

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

local ok, err = pk:set_parameters(parameters)

Paramètres pour la clé RSA :

Paramètre Description Type
n module commun aux clés publique et privée bn
e exposant public bn
d exposant privé bn
p premier facteur de n bn
q deuxième facteur de n bn
dmp1 d mod (p - 1), exponent1 bn
dmq1 d mod (q - 1), exponent2 bn
iqmp (InverseQ)(q) = 1 mod p, coefficient bn

Paramètres pour la clé EC :

Paramètre Description Type
private clé privée bn
public clé publique bn
x coordonnée x de la clé publique bn
y coordonnée y de la clé publique bn
group le groupe de courbe nommé [NID] en tant que nombre, lorsqu'il est passé dans set_parameters(), il est également possible d'utiliser la représentation textuelle. Cela diffère de luaossl où une instance de EC_GROUP est retournée.

Il n'est pas possible de définir x, y avec public en même temps car x et y sont essentiellement une autre représentation de public. De plus, actuellement, il est seulement possible de définir x et y en même temps.

Paramètres pour la clé DH :

Paramètre Description Type
private clé privée bn
public clé publique bn
p module premier bn
q position de référence bn
g générateur de base bn

Paramètres pour les clés Curve25519 et Curve448 :

Paramètre Description Type
private clé privée brute représentée sous forme d'octets chaîne
public clé publique brute représentée sous forme d'octets chaîne

pkey:is_private

syntax: ok = pk:is_private()

Vérifie si pk est une clé privée. Retourne vrai si c'est une clé privée, retourne faux si c'est une clé publique.

pkey:get_key_type

syntax: obj, err = pk:get_key_type(nid_only?)

Retourne un ASN1_OBJECT du type de clé de la clé privée sous forme de table.

À partir de lua-resty-openssl 1.6.0, un argument optionnel nid_only peut être défini sur true pour ne retourner que le NID numérique de la clé.

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

ngx.say(require("cjson").encode(pkey:get_key_type()))
-- affiche '{"ln":"X448","nid":1035,"sn":"X448","id":"1.3.101.111"}'
ngx.say(pkey:get_key_type(true))
-- affiche 1035

pkey:get_size

syntax: size, err = pk:get_size()

Retourne la taille maximale appropriée pour les tampons de sortie pour presque toutes les opérations pouvant être effectuées avec pkey.

Pour une clé RSA, c'est la taille du module. Pour les clés EC, Ed25519 et Ed448, c'est la taille de la clé privée. Pour une clé DH, c'est la taille du module premier.

pkey:get_default_digest_type

syntax: obj, err = pk:get_default_digest_type()

Retourne un ASN1_OBJECT du type de clé de la clé privée sous forme de table. Un champ supplémentaire mandatory est également retourné dans la table, si mandatory est vrai, alors d'autres hachages ne peuvent pas être utilisés.

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

ngx.say(require("cjson").encode(pkey:get_default_digest_type()))
-- affiche '{"ln":"sha256","nid":672,"id":"2.16.840.1.101.3.4.2.1","mandatory":false,"sn":"SHA256"}'

pkey:sign

syntax: signature, err = pk:sign(digest)

syntax: signature, err = pk:sign(message, md_alg?, padding?, opts?)

Effectue une signature de hachage en utilisant la clé privée définie dans l'instance pkey. Le premier paramètre doit être une instance de resty.openssl.digest ou une chaîne. Retourne le texte signé et une erreur le cas échéant.

Lors du passage d'une instance de digest comme premier paramètre, elle ne doit pas avoir été appelée final(), l'utilisateur doit uniquement utiliser update(). Ce mode ne prend en charge que les clés RSA et EC.

Lors du passage d'une chaîne comme premier paramètre, le paramètre md_alg spécifiera le nom à utiliser lors de la signature. Lorsque md_alg est indéfini, pour les clés RSA et EC, cette fonction effectue un SHA256 par défaut. Pour les clés Ed25519 ou Ed448, cette fonction effectue une signature PureEdDSA, aucun hachage de message ne doit être spécifié et ne sera pas utilisé.

Pour une clé RSA, il est également possible de spécifier le schéma de padding avec les choix suivants :

  pkey.PADDINGS = {
    RSA_PKCS1_PADDING       = 1,
    RSA_SSLV23_PADDING      = 2,
    RSA_NO_PADDING          = 3,
    RSA_PKCS1_OAEP_PADDING  = 4,
    RSA_X931_PADDING        = 5, -- signer uniquement
    RSA_PKCS1_PSS_PADDING   = 6, -- signer et vérifier uniquement
  }

Lorsque padding est RSA_PKCS1_PSS_PADDING, il est possible de spécifier la longueur de sel PSS en définissant opts.pss_saltlen.

Pour une clé EC, cette fonction effectue une signature ECDSA. Notez qu'OpenSSL ne prend pas en charge la signature numérique EC (ECDSA) avec l'algorithme de hachage obsolète MD5 et renverra une erreur sur cette combinaison. Voir EVP_DigestSign(3) pour une liste des algorithmes et des algorithmes de clé publique associés. Normalement, la signature ECDSA est encodée au format ASN.1 DER. Si la table opts contient un champ ecdsa_use_raw avec une valeur vraie, un binaire avec juste la concaténation de la représentation binaire pr et ps est retourné. Ceci est utile par exemple pour envoyer la signature en tant que JWS.

opts est une table qui accepte des paramètres supplémentaires avec les choix suivants :

{
  pss_saltlen, -- Pour le mode PSS, cette option spécifie la longueur du sel.
  mgf1_md, -- Pour le remplissage PSS et OAEP, définit le hachage MGF1. Si le hachage MGF1 n'est pas explicitement défini en mode PSS, alors le hachage de signature est utilisé.
  oaep_md, -- Le hachage utilisé pour la fonction de hachage OAEP. Si non défini explicitement, SHA1 est utilisé.
}

Il est également possible de passer des chaînes de contrôle pkeyopt brutes comme utilisé dans le programme CLI pkeyutl. Cela permet à l'utilisateur de passer des options qui ne sont pas explicitement prises en charge comme paramètres ci-dessus. Voir openssl-pkeyutl(1) pour une liste d'options.

pk:sign(message, nil, pk.PADDINGS.RSA_PKCS1_OAEP_PADDING, {
  oaep_md = "sha256",
})
-- est identique à
pk:sign(message, nil, nil, {
  "rsa_padding_mode:oaep",
  "rsa_oaep_md:sha256",
})
-- dans le CLI pkeyutl, ce qui précède équivaut à : `openssl pkeyutl -sign -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256

Pour signer un message sans effectuer de hachage de message, veuillez consulter pkey:sign_raw.

pkey:verify

syntax: ok, err = pk:verify(signature, digest)

syntax: ok, err = pk:verify(signature, message, md_alg?, padding?, opts?)

Vérifie une signature (qui peut être la chaîne retournée par pkey:sign). Le deuxième argument doit être une instance de resty.openssl.digest qui utilise le même algorithme de hachage que celui utilisé dans sign ou une chaîne. ok retourne true si la vérification est réussie et false sinon. Notez que lorsque la vérification échoue, err ne sera pas défini lorsqu'il est utilisé avec OpenSSL 1.1.1 ou inférieur.

Lors du passage d'instances de digest comme deuxième paramètre, elle ne doit pas avoir été appelée final(), l'utilisateur doit uniquement utiliser update(). Ce mode ne prend en charge que les clés RSA et EC.

Lors du passage d'une chaîne comme deuxième paramètre, le paramètre md_alg spécifiera le nom à utiliser lors de la vérification. Lorsque md_alg est indéfini, pour les clés RSA et EC, cette fonction effectue un SHA256 par défaut. Pour les clés Ed25519 ou Ed448, cette fonction effectue une vérification PureEdDSA, aucun hachage de message ne doit être spécifié et ne sera pas utilisé.

Lorsque la clé est une clé RSA, la fonction accepte un argument optionnel padding dont les valeurs sont les mêmes que celles de pkey:sign. Lorsque padding est RSA_PKCS1_PSS_PADDING, il est possible de spécifier la longueur de sel PSS en définissant opts.pss_saltlen.

Pour la clé EC, cette fonction effectue une vérification ECDSA. Normalement, la signature ECDSA doit être encodée au format ASN.1 DER. Si la table opts contient un champ ecdsa_use_raw avec une valeur vraie, cette bibliothèque considère signature comme la concaténation de la représentation binaire pr et ps. Ceci est utile par exemple pour vérifier la signature en tant que JWS.

opts est une table qui accepte des paramètres supplémentaires dont les choix sont les mêmes que ceux de pkey:sign.

-- Clés RSA et EC
local pk, err = require("resty.openssl.pkey").new()
local digest, err = require("resty.openssl.digest").new("SHA256")
digest:update("dog")
-- FAUX :
-- digest:final("dog")
local signature, err = pk:sign(digest)
-- utilise SHA256 par défaut
local signature, err = pk:sign("dog")
ngx.say(ngx.encode_base64(signature))
-- utilise SHA256 et PSS padding
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)
-- utilise SHA256 par défaut
local ok, err = pk:verify(signature, "dog")
-- utilise SHA256 et PSS padding
local ok, err = pk:verify(signature_pss, "dog", "sha256", pk.PADDINGS.RSA_PKCS1_PSS_PADDING)

-- Clés Ed25519 et Ed448
local pk, err = require("resty.openssl.pkey").new({
  type = "Ed25519",
})
local signature, err = pk:sign("23333")
ngx.say(ngx.encode_base64(signature))

Pour vérifier un message sans effectuer de hachage de message, veuillez consulter pkey:verify_raw et pkey:verify_recover.

pkey:encrypt

syntax: cipher_txt, err = pk:encrypt(txt, padding?, opts?)

Chiffre le texte brut txt avec l'instance pkey, qui doit avoir chargé une clé publique.

Le deuxième argument optionnel padding a la même signification que dans pkey:sign. Si omis, padding est par défaut pkey.PADDINGS.RSA_PKCS1_PADDING.

Le troisième argument optionnel opts a la même signification que dans pkey:sign.

pkey:decrypt

syntax: txt, err = pk:decrypt(cipher_txt, padding?, opts?)

Déchiffre le texte chiffré cipher_txt avec l'instance pkey, qui doit avoir chargé une clé privée.

Le deuxième argument optionnel padding a la même signification que dans pkey:sign. Si omis, padding est par défaut pkey.PADDINGS.RSA_PKCS1_PADDING.

Le troisième argument optionnel opts a la même signification que dans 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)
-- affiche 256
local decrypted, err = privkey:decrypt(s)
ngx.say(decrypted)
-- affiche "🦢"

pkey:sign_raw

syntax: signature, err = pk:sign_raw(txt, padding?, opts?)

Signe le texte chiffré cipher_txt avec l'instance pkey, qui doit avoir chargé une clé privée.

Le deuxième argument optionnel padding a la même signification que dans pkey:sign. Si omis, padding est par défaut pkey.PADDINGS.RSA_PKCS1_PADDING.

Le troisième argument optionnel opts a la même signification que dans pkey:sign.

Cette fonction peut également être appelée "chiffrement privé" dans certaines implémentations comme NodeJS ou PHP. Notez qu'en tant que le nom des fonctions le suggère, cette fonction n'est pas sécurisée pour être considérée comme un chiffrement. Lors du développement de nouvelles applications, l'utilisateur doit utiliser pkey:sign pour signer avec un hachage, ou pkey:encrypt pour le chiffrement.

Voir examples/raw-sign-and-recover.lua pour un exemple.

pkey:verify_raw

syntax: ok, err = pk:verify_raw(signature, data, md_alg, padding?, opts?)

Vérifie le texte chiffré signature avec le message data avec l'instance pkey, qui doit avoir chargé une clé publique. Définit le hachage du message sur md_alg mais ne fait pas de hachage de message automatiquement, en d'autres termes, cette fonction suppose que data a déjà été haché avec md_alg.

Lorsque md_alg est indéfini, pour les clés RSA et EC, cette fonction effectue un SHA256 par défaut. Pour les clés Ed25519 ou Ed448, aucune valeur par défaut n'est définie.

Le quatrième argument optionnel padding a la même signification que dans pkey:sign. Si omis, padding est par défaut pkey.PADDINGS.RSA_PKCS1_PADDING.

Le cinquième argument optionnel opts a la même signification que dans pkey:sign.

Voir examples/raw-sign-and-recover.lua pour un exemple.

pkey:verify_recover

syntax: txt, err = pk:verify_recover(signature, padding?, opts?)

Vérifie le texte chiffré signature avec l'instance pkey, qui doit avoir chargé une clé publique, et retourne également le texte original signé. Cette opération n'est prise en charge que par la clé RSA.

Le deuxième argument optionnel padding a la même signification que dans pkey:sign. Si omis, padding est par défaut pkey.PADDINGS.RSA_PKCS1_PADDING.

Le troisième argument optionnel opts a la même signification que dans pkey:sign.

Cette fonction peut également être appelée "décryptage public" dans certaines implémentations comme NodeJS ou PHP.

Voir examples/raw-sign-and-recover.lua pour un exemple.

pkey:derive

syntax: txt, err = pk:derive(peer_key)

Dérive la clé secrète partagée de l'algorithme de clé publique peer_key, qui doit être une instance de pkey.

Voir examples/x25519-dh.lua pour un exemple sur le fonctionnement de l'échange de clés pour les clés X25519 avec l'algorithme DH.

pkey:tostring

syntax: txt, err = pk:tostring(private_or_public?, fmt?, is_pkcs1?)

Affiche la clé privée ou publique de l'instance pkey sous forme de texte au format PEM. Le premier argument doit être un choix de public, PublicKey, private, PrivateKey ou nil.

Le deuxième argument fmt peut être PEM, DER, JWK ou nil. Si les deux arguments sont omis, cette fonction retourne la représentation PEM de la clé publique.

Si is_pkcs1 est défini sur true, la sortie est encodée en utilisant une structure PKCS#1 RSAPublicKey ; l'encodage PKCS#1 est actuellement pris en charge pour la clé RSA au format PEM. Écrire une clé RSA encodée PKCS#1 n'est actuellement pas pris en charge lors de l'utilisation avec OpenSSL 3.0.

pkey:to_PEM

syntax: pem, err = pk:to_PEM(private_or_public?, is_pkcs1?)

Équivalent à pkey:tostring(private_or_public, "PEM", is_pkcs1).

resty.openssl.bn

Module pour exposer la structure BIGNUM. Notez que bignum est un grand entier, aucune opération flottante (comme la racine carrée) n'est prise en charge.

bn.new

syntax: b, err = bn.new(number?)

syntax: b, err = bn.new(string?, base?)

Crée une instance bn. Le premier argument peut être :

  • nil pour créer une instance bn vide.
  • Un nombre Lua pour initialiser l'instance bn.
  • Une chaîne pour initialiser l'instance bn. Le deuxième argument base spécifie la base de la chaîne, et peut prendre les valeurs suivantes (compatible avec l'API Ruby OpenSSL.BN) :
  • 10 ou omis, pour une chaîne décimale ("23333")
  • 16, pour une chaîne encodée en hexadécimal ("5b25")
  • 2, pour une chaîne binaire ("\x5b\x25")
  • 0, pour une chaîne formatée MPI ("\x00\x00\x00\x02\x5b\x25")

MPI est un format qui consiste en la longueur du nombre en octets représentée sous forme d'un nombre big-endian de 4 octets, et le nombre lui-même au format big-endian, où le bit le plus significatif signale un nombre négatif (la représentation des nombres avec le MSB défini est préfixée par un octet nul).

bn.dup

syntax: b, err = bn.dup(bn_ptr_cdata)

Duplique un BIGNUM* pour créer une nouvelle instance bn.

bn.istype

syntax: ok = bn.istype(table)

Retourne true si la table est une instance de bn. Retourne false sinon.

bn.set

syntax: b, err = bn:set(number)

syntax: b, err = bn:set(string, base?)

Réutilise l'instance bn existante et réinitialise sa valeur avec le nombre ou la chaîne donnée. Référez-vous à bn.new pour le type d'arguments pris en charge.

bn.from_binary, bn:to_binary

syntax: bn, err = bn.from_binary(bin)

syntax: bin, err = bn:to_binary(padto?)

Crée une instance bn à partir d'une chaîne binaire.

Exporte la valeur BIGNUM sous forme de chaîne binaire.

bn:to_binary accepte un argument numérique optionnel padto qui peut être utilisé pour ajouter des zéros en tête à la sortie à une longueur spécifique.

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))
-- affiche "5b25"

bn.from_mpi, bn:to_mpi

syntax: bn, err = bn.from_mpi(bin)

syntax: bin, err = bn:to_mpi()

Crée une instance bn à partir d'une chaîne binaire formatée MPI.

Exporte la valeur BIGNUM sous forme de chaîne binaire formatée 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))
-- affiche "000000025b25"

bn.from_hex, bn:to_hex

syntax: bn, err = bn.from_hex(hex)

syntax: hex, err = bn:to_hex()

Crée une instance bn à partir d'une chaîne encodée en hexadécimal. Notez que le préfixe 0x ne doit pas être inclus. Un préfixe - indiquant le signe peut être inclus.

Exporte l'instance bn vers une chaîne encodée en hexadécimal.

local bn = require("resty.openssl.bn")
local b = bn.from_hex("5B25")
local hex, err = b:to_hex()
ngx.say(hex)
-- affiche "5B25"

bn.from_dec, bn:to_dec

syntax: bn, err = bn.from_dec(dec)

syntax: dec, err = bn:to_dec()

Crée une instance bn à partir d'une chaîne décimale. Un préfixe - indiquant le signe peut être inclus.

Exporte l'instance bn vers une chaîne décimale.

local bn = require("resty.openssl.bn")
local b = bn.from_dec("23333")
local dec, err = b:to_dec()
ngx.say(dec)
-- affiche "23333"

bn:to_number

syntax: n, err = bn:to_number()

syntax: n, err = bn:tonumber()

Exporte les 32 bits ou 64 bits les plus bas (selon l'ABI) de l'instance bn vers un nombre. Cela est utile lorsque l'utilisateur souhaite effectuer des opérations bit à bit.

local bn = require("resty.openssl.bn")
local b = bn.from_dec("23333")
local n, err = b:to_number()
ngx.say(n)
-- affiche 23333
ngx.say(type(n))
-- affiche "number"

bn.generate_prime

syntax: bn, err = bn.generate_prime(bits, safe)

Génère un nombre premier pseudo-aléatoire de longueur de bits bits.

Si safe est vrai, ce sera un premier sûr (c'est-à-dire un premier p tel que (p-1)/2 est également premier).

Le PRNG doit être initialisé avant d'appeler BN_generate_prime_ex(). La génération de nombres premiers a une probabilité d'erreur négligeable.

bn:__metamethods

Diverses opérations mathématiques peuvent être effectuées comme si c'était un nombre.

local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(222)
 -- ce qui suit retourne un bn
local r
r = -a
r = a + b
r = a - b
r = a * b
r = a / b -- égal à bn:idiv, retourne la division entière
r = a % b
-- toutes les opérations peuvent être effectuées entre un nombre et un bignum
r = a + 222
r = 222 + a
-- ce qui suit retourne un booléen
local bool
bool = a < b
bool = a >= b
-- la comparaison entre un nombre ne fonctionnera pas
-- FAUX: bool = a < 222

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

syntax: r = a:op(b)

syntax: r = bn.op(a, b)

Effectue des opérations mathématiques op.

  • add: additionner
  • sub: soustraire
  • mul: multiplier
  • div, idiv: division entière (division avec arrondi vers le bas au nombre entier le plus proche)
  • exp, pow: la puissance b-ième de a, cette fonction est plus rapide que a * a * ....
  • mod: modulo
  • gcd: le plus grand diviseur commun de a et b.

Notez que add, sub, mul, div, mod est également disponible avec les opérateurs +, -, *, /, %. Voir section ci-dessus pour des exemples.

local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(9876)
local r
-- les suivants sont égaux
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

syntax: r = a:sqr()

syntax: r = bn.sqr(a)

Calcule la puissance 2 de a. Cette fonction est plus rapide que r = a * a.

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

syntax: r = a:op(b, m)

syntax: r = bn.op(a, b, m)

Effectue des opérations mathématiques modulo op.

  • mod_add: ajoute a à b modulo m
  • mod_sub: soustrait b de a modulo m
  • mod_mul: multiplie a par b et trouve le reste non négatif par rapport au module m
  • mod_exp, mod_pow: calcule a à la puissance b modulo m (r=a^b % m). Cette fonction utilise moins de temps et d'espace que exp. Ne pas appeler cette fonction lorsque m est pair et que l'un des paramètres a le drapeau BN_FLG_CONSTTIME défini.
local bn = require("resty.openssl.bn")
local a = bn.new(123456)
local b = bn.new(9876)
local r
-- les suivants sont égaux
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

syntax: r = a:mod_sqr(m)

syntax: r = bn.mod_sqr(a, m)

Prend le carré de a modulo m.

bn:lshift, bn:rshift

syntax: r = bn:lshift(bit)

syntax: r = bn.lshift(a, bit)

syntax: r = bn:rshift(bit)

syntax: r = bn.rshift(a, bit)

Décale les bits de a vers bit bits.

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

syntax: ok = bn:is_zero()

syntax: ok = bn:is_one()

syntax: ok = bn:is_odd()

syntax: ok, err = bn:is_word(n)

Vérifie si bn est 0, 1, un nombre impair ou un nombre n respectivement.

bn:is_prime

syntax: ok, err = bn:is_prime(nchecks?)

Vérifie si bn est un nombre premier. Retourne true s'il est premier avec une probabilité d'erreur inférieure à 0.25^nchecks et une erreur le cas échéant. Si omis, nchecks est défini sur 0, ce qui signifie sélectionner le nombre d'itérations basé sur la taille du nombre.

Cette fonction effectue un test de primalité probabiliste de Miller-Rabin avec nchecks itérations. Si nchecks == BN_prime_checks (0), un nombre d'itérations est utilisé qui donne un taux de faux positif d'au plus 2^-64 pour une entrée aléatoire. Le taux d'erreur dépend de la taille du premier et diminue pour des premiers plus grands. Le taux est de 2^-80 à partir de 308 bits, 2^-112 à 852 bits, 2^-128 à 1080 bits, 2^-192 à 3747 bits et 2^-256 à 6394 bits.

Lorsque la source du premier n'est pas aléatoire ou non fiable, le nombre de vérifications doit être beaucoup plus élevé pour atteindre le même niveau d'assurance : il doit être égal à la moitié du niveau de sécurité ciblé en bits (arrondi à l'entier supérieur si nécessaire). Par exemple, pour atteindre le niveau de sécurité de 128 bits, nchecks doit être défini sur 64.

Voir aussi BN_is_prime(3).

resty.openssl.cipher

Module pour interagir avec la cryptographie symétrique (EVP_CIPHER).

cipher.new

syntax: d, err = cipher.new(cipher_name, properties?)

Crée une instance de chiffrement. cipher_name est une chaîne insensible à la casse du nom de l'algorithme de chiffrement. Pour voir une liste des algorithmes de chiffrement implémentés, utilisez openssl.list_cipher_algorithms ou openssl list -cipher-algorithms.

À partir d'OpenSSL 3.0, cette fonction accepte un paramètre properties optionnel pour sélectionner explicitement le fournisseur pour récupérer les algorithmes.

cipher.istype

syntax: ok = cipher.istype(table)

Retourne true si la table est une instance de cipher. Retourne false sinon.

cipher.set_buffer_size

syntax: ok = cipher.set_buffer_size(sz)

Redimensionne la taille du tampon interne utilisée par toutes les instances de chiffrement. La taille de tampon par défaut est de 1024 octets.

Si vous prévoyez de passer un texte d'entrée supérieur à 1024 octets à la fois à update(), encrypt() ou decrypt(), définir le tampon à une taille supérieure à la taille d'entrée attendue améliorera les performances en permettant à plus de code d'être JIT-able.

Évitez d'appeler cette fonction dans le chemin chaud, car cela réalloue le tampon chaque fois qu'elle est appelée.

cipher:get_provider_name

syntax: name = cipher:get_provider_name()

Retourne le nom du fournisseur de cipher.

Cette fonction est disponible depuis OpenSSL 3.0.

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

Interroger les paramètres réglables ou récupérables et définir ou obtenir des paramètres. Voir Generic EVP parameter getter/setter.

cipher:encrypt

syntax: s, err = cipher:encrypt(key, iv?, s, no_padding?, aead_aad?)

Chiffre le texte s avec la clé key et l'IV iv. Retourne le texte chiffré sous forme de chaîne binaire brute et une erreur le cas échéant. Accepte en option un booléen no_padding qui indique au chiffrement d'activer ou de désactiver le remplissage et par défaut à false (activer le remplissage). Si no_padding est true, la longueur de s doit alors être un multiple de la taille de bloc ou une erreur se produira.

Lors de l'utilisation du mode GCM ou CCM ou de l'algorithme de chiffrement chacha20-poly1305, il est également possible de passer les Données Authentifiées Supplémentaires (AAD) comme cinquième argument.

Cette fonction est un raccourci de cipher:init, cipher:set_aead_aad (si applicable) puis cipher:final.

cipher:decrypt

syntax: s, err = cipher:decrypt(key, iv?, s, no_padding?, aead_aad?, aead_tag?)

Déchiffre le texte s avec la clé key et l'IV iv. Retourne le texte déchiffré sous forme de chaîne binaire brute et une erreur le cas échéant. Accepte en option un booléen no_padding qui indique au chiffrement d'activer ou de désactiver le remplissage et par défaut à false (activer le remplissage). Si no_padding est true, la longueur de s doit alors être un multiple de la taille de bloc ou une erreur se produira ; de plus, le remplissage dans le texte déchiffré ne sera pas supprimé.

Lors de l'utilisation du mode GCM ou CCM ou de l'algorithme de chiffrement chacha20-poly1305, il est également possible de passer les Données Authentifiées Supplémentaires (AAD) comme cinquième argument et le tag d'authentification comme sixième argument.

Cette fonction est un raccourci de cipher:init, cipher:set_aead_aad (si applicable), cipher:set_aead_tag (si applicable) puis cipher:final.

cipher:init

syntax: ok, err = cipher:init(key, iv?, opts?)

Initialise le chiffrement avec la clé key et l'IV iv. Le troisième argument optionnel est une table composée de :

{
    is_encrypt = false,
    no_padding = false,
}

Appeler cette fonction est nécessaire avant cipher:update et cipher:final si le chiffrement n'est pas déjà initialisé. Mais pas pour cipher:encrypt et cipher:decrypt.

Si vous souhaitez réutiliser l'instance cipher plusieurs fois, appeler cette fonction est nécessaire pour effacer l'état interne du chiffrement. Les fonctions raccourcies cipher:encrypt et cipher:decrypt s'occupent déjà de l'initialisation et de la réinitialisation.

cipher:update

syntax: s, err = cipher:update(partial, ...)

Met à jour le chiffrement avec une ou plusieurs chaînes. Si le chiffrement a plus de données que la taille de bloc à vider, la fonction retournera une chaîne non vide comme premier argument. Cette fonction peut être utilisée de manière continue pour chiffrer ou déchiffrer un flux de données continu.

cipher:update_aead_aad

syntax: ok, err = cipher:update_aead_aad(aad)

Fournit des données AAD au chiffrement, cette fonction peut être appelée plusieurs fois.

cipher:get_aead_tag

syntax: tag, err = cipher:get_aead_tag(size?)

Obtient le tag d'authentification du chiffrement avec une longueur spécifiée comme size. Si omis, un tag de longueur de la moitié de la taille de bloc sera retourné. La taille ne peut pas dépasser la taille de bloc.

Cette fonction ne peut être appelée qu'après la fin du chiffrement.

cipher:set_aead_tag

syntax: ok, err = cipher:set_aead_tag(tag)

Définit le tag d'authentification du chiffrement avec tag.

Cette fonction ne peut être appelée qu'avant le début du déchiffrement.

cipher:final

syntax: s, err = cipher:final(partial?)

Retourne le texte chiffré ou déchiffré sous forme de chaîne binaire brute, accepte en option une chaîne à chiffrer ou déchiffrer.

-- chiffrement
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))
-- affiche "vGJRHufPYrbbnYYC0+BnwQ=="
-- OU :
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))
-- affiche "vGJRHufPYrbbnYYC0+BnwQ=="

-- déchiffrement
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)
-- affiche "🦢"
-- OU :
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)
-- affiche "🦢"

Remarque : dans certaines implémentations comme libsodium ou Java, les chiffrements AEAD ajoutent le tag (ou MAC) à la fin du texte chiffré. Dans ce cas, l'utilisateur devra manuellement couper le tag avec la taille correcte (généralement 16 octets) et passer séparément le texte chiffré et le tag.

Voir examples/aes-gcm-aead.lua pour un exemple d'utilisation des modes AEAD avec authentification.

cipher:derive

syntax: key, iv, err = cipher:derive(key, salt?, count?, md?)

Dérive une clé et un IV (si applicable) à partir du matériel donné qui peut être utilisé dans le chiffrement actuel. Cette fonction est principalement utile pour travailler avec des clés qui ont déjà été dérivées du même algorithme. Les nouvelles applications devraient utiliser un algorithme plus moderne tel que PBKDF2 fourni par kdf.derive.

count est le nombre d'itérations à effectuer. S'il est omis, il est défini sur 1. Notez que la version récente de l'outil CLI openssl enc utilise automatiquement PBKDF2 si -iter est défini sur plus de 1, tandis que cette fonction ne le fera pas. Pour utiliser PBKDF2 pour dériver une clé, veuillez vous référer à kdf.derive.

md est le nom du hachage de message à utiliser, il peut prendre l'une des valeurs md2, md5, sha ou sha1. S'il est omis, il est par défaut sha1.

local cipher = require("resty.openssl.cipher").new("aes-128-cfb")
local key, iv, err = cipher:derive("x")
-- équivalent à `openssl enc -aes-128-cfb -pass pass:x -nosalt -P -md sha1`

resty.openssl.digest

Module pour interagir avec le hachage de message (EVP_MD_CTX).

digest.new

syntax: *d, err = digest.new(digest_name?,