Emballer et déballer une clé
Les deux points de terminaison du mode enveloppe, actif par défaut. Ce sont eux que vos écritures et vos lectures appellent réellement.
MAFATE ne reçoit qu’une clé de données de 32 octets
Ni le champ, ni le chiffré, ni sa taille. La donnée est chiffrée dans votre processus, avec une clé de données que vous tirez et que nous emballons. Une compromission de MAFATE seule ne permet donc rien : il faudrait aussi compromettre votre base.
| Endpoint | Corps | Réponse | Permission |
|---|---|---|---|
| POST /v1/keys/:id/wrap | { "dek": base64 } | { "wrapped_key", "key_version" } | keys:wrap |
| POST /v1/keys/:id/unwrap | { "wrapped_key": string } | { "dek": base64 } | keys:wrap |
Une seule permission couvre les deux, et c’est voulu : keys:wrap est le geste quotidien. keys:export, qui rend toutes les clés de données d’un coup, est délibérément distincte pour qu’une capacité de sortie ne soit jamais accordée par effet de bord.
Emballer une clé de données
# La cle de donnees est tiree CHEZ VOUS : 32 octets, base64 standard.
DEK=$(head -c 32 /dev/urandom | base64)
curl -s -X POST "https://api.mafate.io/v1/keys/7c9e6679-7425-40de-944b-e07fc1f90ae7/wrap" \
-H "Authorization: Bearer $MAFATE_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"dek\":\"$DEK\"}"
# Reponse 200
{
"wrapped_key": "CiQAe3kL9vXmPqR7sT2uV4wX6yZ8aB0cD1eF3gH5iJ7kL9mN...",
"key_version": 3
}
# ⚠️ `wrapped_key` est un jeton OPAQUE. N'essayez pas de l'interpreter, de le
# tronquer ni de le recomposer : son format interne peut changer, seule sa
# presentation a /unwrap est stable.
# 409 si la cle n'est pas active : seule une cle active peut emballer.
# 400 si la DEK ne fait pas exactement 32 octets. Ce controle est strict
# DELIBEREMENT : accepter 16 octets degraderait silencieusement l'AES-256
# annonce, tout continuerait de fonctionner avec la moitie de la force.Déballer une clé de données
curl -s -X POST "https://api.mafate.io/v1/keys/7c9e6679-7425-40de-944b-e07fc1f90ae7/unwrap" \
-H "Authorization: Bearer $MAFATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"wrapped_key":"CiQAe3kL9vXmPqR7sT2uV4wX6yZ8aB0cD1eF3gH5iJ7kL9mN..."}'
# Reponse 200
{
"dek": "3q2+7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
}
# 403 si le jeton ne s'authentifie pas pour CETTE cle.
{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "wrapped_key could not be authenticated for this key"
}
# ⚠️ CE MESSAGE EST LE MEME POUR UN JETON CORROMPU ET POUR UN JETON APPARTENANT
# A UN AUTRE LOCATAIRE, et c'est deliberé. Distinguer les deux renseignerait un
# attaquant sur l'existence du jeton ailleurs.
# 500 « unwrap refused: audit trail could not be recorded » : la cle N'EST PAS
# rendue si son entree d'audit n'a pas pu etre ecrite. Voir plus bas.Le format d’enveloppe
Six champs, tous obligatoires. Il en manque un seul et la donnée est définitivement illisible, sans que rien n’ait signalé le problème au moment de l’écriture. C’est le défaut le plus coûteux de cette intégration, et le plus facile à commettre en passant par un ORM ou un bus de messages.
| Champ | Description |
|---|---|
| ciphertext | Chiffré base64, avec le tag GCM concaténé à la fin (16 octets) |
| wrapped_key | Jeton opaque rendu par wrap. Lié au locataire et à la clé. |
| iv | IV base64 de 12 octets, tiré à chaque opération |
| key_id | UUID de la clé, pas son nom |
| key_version | Version de la clé au moment de l’emballage |
| envelope_version | Vaut 1. Permet une migration future du format sans ambiguïté. |
Trois comportements à connaître
Un IV réutilisé casse GCM en silence
Chiffrer deux valeurs avec la même clé de données et le même IV rompt la confidentialité, sans provoquer la moindre erreur. Tirez-en un neuf à chaque opération. C’est la seule règle de cette page dont la violation ne produit aucun signal.
unwrap échoue fermé si l’audit ne peut pas être écrit
En mode enveloppe, MAFATE ne voit jamais la donnée : l’entrée d’audit est le seul témoin qu’une clé de données est sortie. Rendre la clé sans trace confirmée autoriserait une exfiltration invisible, donc l’appel répond 500 plutôt que de servir la clé. Le coût de disponibilité est nul en pratique : unwrap a déjà besoin de la base pour charger la version de clé, et l’audit écrit dans la même base.
L’effacement de la clé de données n’est garanti qu’en Go
Les SDK Node.js et Python remplissent la clé de données de zéros après usage, ce qui vaut mieux que rien mais ne garantit pas son effacement : le moteur a pu en copier le contenu ailleurs dans le tas. Le SDK Go est le seul des trois à pouvoir le garantir. Ce n’est pas une raison de changer de langage, c’est une raison de ne pas prétendre le contraire dans votre analyse de risque.