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. Ensuite, vous pouvez procéder avec les étapes suivantes.
CentOS/RHEL 7 ou 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
Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.
Ce document décrit lua-resty-openssl v1.8.0 publié le 10 juin 2026.
Liaison OpenSSL basée sur FFI pour LuaJIT, prenant en charge OpenSSL 3, 4 et la série 1.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.
Description
lua-resty-openssl est une bibliothèque de liaison OpenSSL basée sur FFI, prenant actuellement en charge OpenSSL 3.x, 4.x et la série 1.1.1.
Synopsis
Cette bibliothèque est fortement inspirée par luaossl et utilise 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 est exposée comme 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 en tant que 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 par rapport à 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 modèles de noms de bibliothèques connus et retourne le nom de la bibliothèque crypto lorsqu'elle est chargée avec succès, ou une erreur si quelque chose ne va pas.
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, mac et ctx sont également disponibles.
openssl.luaossl_compat
syntax: openssl.luaossl_compat()
Fournit une API au goût de luaossl qui utilise la convention de nommage camelCase ; les utilisateurs peuvent s'attendre à un remplacement direct.
Par exemple, pkey:get_parameters est mappé à pkey:getParameters.
Notez que toutes les API luaossl n'ont pas été implémentées, 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)
Active ou désactive le mode FIPS.
lua-resty-openssl prend en charge les modes suivants :
Série OpenSSL 1.0.2 avec module fips 2.0
Compilez le module selon la politique de sécurité,
Fournisseur FIPS OpenSSL 3
Référez-vous à https://wiki.openssl.org/index.php/OpenSSL_3.0 Section 7 Compilez le fournisseur selon le guide, installez le fipsmodule.cnf qui correspond au hash du fournisseur FIPS fips.so.
À partir d'OpenSSL 3.0, 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()) -- imprime "default"
local c = assert(cipher.new("aes256", "fips=yes"))
print(c:get_provider_name()) -- imprime "fips"
openssl.get_fips_version_text
syntax: text, err = openssl.get_fips_version_text()
Retourne le texte de version du module FIPS, disponible sur OpenSSL 3.0 ou ultérieur.
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 fetching 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 4.x rejette "SSLv3" car le support de SSLv3 a été
supprimé.
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 commutateurs 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 des 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 :
- cipher
- digest
- kdf
- mac
- pkcs12.encode
- pkey
- provider
- rand
- x509, x509.csr, x509.crl et certaines fonctions x509.store
Ce module est disponible 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 de 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 GC'ed
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]:
Pour les versions d'OpenSSL antérieures à 3.0, 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 fonctionne uniquement sur OpenSSL 3.0 ou ultérieur.
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 à utiliser 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)
-- outputs "OpenSSL Default Provider"
local result = assert(p:get_params("name", "version", "buildinfo", "status"))
print(require("cjson").encode(result))
-- outputs metadata du fournisseur ; version et buildinfo varient selon la version d'OpenSSL
resty.openssl.pkey
Module pour interagir avec les clés privées et publiques (EVP_PKEY).
Chaque type de clé peut uniquement prendre en charge certaines 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 de chargement de clé.
opts.format: défini explicitement sur"PEM","DER","JWK"pour charger un format spécifique ou défini sur"*"pour auto-détecteropts.type: défini explicitement sur"pr"pour clé privée,"pu"pour clé publique ; défini sur"*"pour auto-détecter
Lors du chargement d'une clé RSA encodée en PEM, elle 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 et chiffrée, le passphrase pour la déchiffrer peut être défini soit dans opts.passphrase, soit dans opts.passphrase_cb :
pkey.new(pem_or_der_text, {
format = "*", -- choix de "PEM", "DER", "JWK" ou "*" pour auto-détecter
type = "*", -- choix de "pr" pour clé privée, "pu" pour clé publique et "*" pour auto-détecter
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.
- Contraindre opts.type pour les clés JWK nécessite OpenSSL 3.0 ou ultérieur et
lua-resty-openssl 1.6.0 ou ultérieur. Avec OpenSSL 1.1.1 ou une version antérieure,
les versions de lua-resty-openssl, 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érer un nouveau paramètre DH avec un prime de longueur bits. Si omis, par défaut à 2048. À partir d'OpenSSL 3.0, seuls des bits égaux à 2048 sont autorisés. |
| group | Utilisez des groupes prédéfinis au lieu de 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 sur OpenSSL 3.0 ou ultérieur.
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())
-- outputs 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 | second 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] sous forme de 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 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 n'est possible de définir x et y qu'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()))
-- outputs '{"ln":"X448","nid":1035,"sn":"X448","id":"1.3.101.111"}'
ngx.say(pkey:get_key_type(true))
-- outputs 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 qui peuvent être effectuées avec pkey.
Pour la 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 la 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()))
-- outputs '{"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 pkey.
Le premier paramètre doit être une instance de resty.openssl.digest
ou une chaîne. Retourne le texte signé et une erreur si quelque chose ne va pas.
Lors du passage d'une instance de digest comme premier paramètre, elle ne doit pas avoir été appelée final() ; les utilisateurs doivent 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 n'est pas défini, pour les clés RSA et EC, cette fonction utilise 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 la 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 la 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 d'algorithmes et d'algorithmes de clés publiques 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 pkeyutl CLI. Cela permet aux utilisateurs de passer des options qui
ne sont pas explicitement prises en charge en tant que 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 pkeyutl CLI, 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() ; les utilisateurs doivent 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 n'est pas défini, pour les clés RSA et EC, cette fonction utilise 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 choix
de valeurs sont les mêmes que ceux 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 traite 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
de valeurs 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 en clair txt avec une instance pkey, qui doit contenir une clé publique.
Le second argument optionnel padding a la même signification que dans pkey:sign.
S'il est omis, padding 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 une instance pkey, qui doit contenir une clé privée.
Le second argument optionnel padding a la même signification que dans pkey:sign.
S'il est omis, padding 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)
-- outputs 256
local decrypted, err = privkey:decrypt(s)
ngx.say(decrypted)
-- outputs "🦢"
pkey:sign_raw
syntax: signature, err = pk:sign_raw(txt, padding?, opts?)
Signe le texte chiffré cipher_txt avec une instance pkey, qui doit contenir une clé privée.
Le second argument optionnel padding a la même signification que dans pkey:sign.
S'il est omis, padding 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 que malgré le nom de la fonction, cette fonction n'est pas suffisamment sécurisée pour être considérée comme un chiffrement. Lors du développement de nouvelles applications, les utilisateurs devraient 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 en utilisant une instance pkey, qui doit contenir une clé publique.
Il définit le hachage de message sur md_alg mais ne calcule pas le hachage de message
automatiquement ; en d'autres termes, cette fonction suppose que data a déjà été haché avec md_alg.
Lorsque md_alg n'est pas défini, pour les clés RSA et EC, cette fonction utilise 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.
S'il est omis, padding 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 une instance pkey, qui doit contenir une clé publique, et retourne également le texte original signé. Cette opération n'est prise en charge que par la clé RSA.
Le second argument optionnel padding a la même signification que dans pkey:sign.
S'il est omis, padding 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échiffrement 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 de 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?)
Sort le clé privée ou publique de l'instance pkey au format texte PEM.
Le premier argument doit être un choix de public, PublicKey, private, PrivateKey ou nil.
Le second 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 vrai, la sortie est encodée en utilisant une structure RSAPublicKey PKCS#1 ;
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 d'OpenSSL 3.0 ou ultérieur.
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 :
nilpour 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
basespécifie la base de la chaîne, et peut prendre les valeurs suivantes (compatible avec l'API Ruby OpenSSL.BN) : 10ou 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 comme 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 jusqu'à 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))
-- outputs "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))
-- outputs "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 sous forme de 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)
-- outputs "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 sous forme de 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)
-- outputs "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 les utilisateurs souhaitent 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)
-- outputs 23333
ngx.say(type(n))
-- outputs "number"
bn.generate_prime
syntax: bn, err = bn.generate_prime(bits, safe)
Génère un nombre premier pseudo-aléatoire de longueur en bits bits.
Si safe est vrai, il s'agira d'un premier sûr (c'est-à-dire un premier p tel que (p-1)/2 est également premier).
Le PRNG doit être semé 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)
-- le suivant 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
-- le suivant retourne un booléen
local bool
bool = a < b
bool = a >= b
-- la comparaison entre les nombres 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: additionnersub: soustrairemul: multiplierdiv,idiv: division entière (division avec arrondi vers le bas au nombre entier le plus proche)exp,pow: la puissanceb-ième dea, cette fonction est plus rapide quea * a * ....mod: modulogcd: le plus grand diviseur commun deaetb.
Notez que add, sub, mul, div, mod sont également disponibles 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: ajouteaàbmodulommod_sub: soustraitbdeamodulommod_mul: multiplieaparbet trouve le reste non négatif par rapport au modulemmod_exp,mod_pow: calculeaà la puissancebmodulom(r=a^b % m). Cette fonction utilise moins de temps et d'espace queexp. Ne pas appeler cette fonction lorsquemest pair et que l'un des paramètres a le drapeauBN_FLG_CONSTTIMEdé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, et 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 si quelque chose ne va pas. Si omis,
nchecks est défini sur 0, ce qui signifie sélectionner le nombre d'itérations en fonction de
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 les plus grands premiers. 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 de garantie : 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 afin de 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 vous attendez à passer un texte d'entrée plus grand que 1024 octets à la fois à update(), encrypt()
ou decrypt(), définir le tampon à une taille supérieure à celle de l'entrée attendue améliorera les performances
en permettant à plus de code d'être JIT-able.
Évitez d'appeler cette fonction sur 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 sur OpenSSL 3.0 ou ultérieur.
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 si quelque chose ne va pas.
Accepte éventuellement 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) en tant que 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 si quelque chose ne va pas.
Accepte éventuellement 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) en tant que cinquième argument et le tag d'authentification
en tant que 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 renverra 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 éventuellement 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))
-- outputs "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))
-- outputs "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)
-- outputs "🦢"
-- 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)
-- outputs "🦢"
Remarque : dans certaines implémentations comme libsodium ou Java, les chiffrements AEAD ajoutent le tag (ou MAC)
à la fin du texte chiffré. Dans de tels cas, les utilisateurs devront manuellement couper le tag
avec la taille correcte (généralement 16 octets) et passer le texte chiffré et le tag séparément.
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 à partir 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 les versions récentes de l'outil CLI openssl enc utilisent 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 par défaut à sha1.
``lua
local cipher = require("resty.openssl.cipher").new("aes-128-cfb")
local key, iv, err = cipher:derive("x")
-- équivalent àopenssl enc -aes-128-c