
Bibliothèque de chiffrement hybride post-quantique combinant X25519 + ML-KEM-768 avec AES-256-GCM
Serveur de chiffrement hybride post-quantique et de gestion de clés.
Citadel combine X25519 + ML-KEM-768 pour l'encapsulation de clés et AES-256-GCM pour le chiffrement des données, suivant l'approche hybride du NIST pour la transition post-quantique. Les applications chiffrent et déchiffrent les données via une API REST. Citadel gère les clés — génération, rotation, révocation, contrôle d'accès et journalisation d'audit.
Statut : Implémentation fonctionnelle. Non audité. Aucun déploiement en production. Voir Sécurité ci-dessous.
Your Application Citadel Database
| | |
|-- POST /encrypt ------->| |
| |-- hybrid KEM (X25519+ML-KEM) |
| |-- derive AES-256 key (HKDF) |
| |-- encrypt with AES-256-GCM |
|<-- encrypted blob ------| |
| |
|-- store blob ------------------------------------------>|
Votre application ne manipule jamais de matière première de clé. Le blob chiffré est autonome — il contient la clé enveloppée, les identifiants d'algorithme et le texte chiffré. Stockez-le dans n'importe quelle base de données. Déchiffrez-le en le renvoyant à Citadel avec les mêmes AAD et contexte.
citadel-envelope Cœur de chiffrement hybride (X25519 + ML-KEM-768 + AES-256-GCM)
citadel-keystore Gestion du cycle de vie des clés, hiérarchie à 4 niveaux, politiques adaptatives aux menaces
citadel-api Serveur HTTP, authentification par clé API limitée, limitation de débit, tableau de bord en temps réel
# Cloner
git clone https://github.com/mrcord77/rust_citadel.git
cd rust_citadel
# Définir votre clé API administrateur
echo -n "your-secret-key" | sha256sum | cut -d' ' -f1
# Copier le hash
# Démarrer
CITADEL_API_KEY_HASH=<paste-hash> docker compose up -d
# Vérifier
curl http://localhost:3000/health
# {"status":"ok","version":"0.2.0"}
Tableau de bord : http://localhost:3000
Nécessite Rust 1.75+.
cargo build --release -p citadel-api
CITADEL_API_KEY="your-secret-key" CITADEL_SEED_DEMO=true ./target/release/citadel-api
import requests
api = "http://localhost:3000"
headers = {"Authorization": "Bearer your-secret-key"}
# Chiffrer
r = requests.post(f"{api}/api/keys/{dek_id}/encrypt", headers=headers, json={
"plaintext": "sensitive data",
"aad": "record-001", # lie le texte chiffré à cet enregistrement
"context": "patient-records" # séparation de domaine
})
blob = r.json()
# Déchiffrer
r = requests.post(f"{api}/api/decrypt", headers=headers, json={
"blob": blob,
"aad": "record-001",
"context": "patient-records"
})
plaintext = r.json()["plaintext"]
Voir citadel_example.py pour un exemple complet fonctionnel avec liaison AAD, rotation de clé et comportement adaptatif aux menaces.
# Statut
curl http://localhost:3000/api/status -H "Authorization: Bearer $KEY"
# Lister les clés
curl http://localhost:3000/api/keys -H "Authorization: Bearer $KEY"
# Chiffrer
curl -X POST http://localhost:3000/api/keys/$DEK_ID/encrypt \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"plaintext":"hello","aad":"test","context":"demo"}'
| Point de terminaison | Méthode | Portée | Description |
|---|---|---|---|
/health | GET | — | Vérification de santé |
/api/status | GET | read | Niveau de menace, nombre de clés |
/api/metrics | GET | read | Métriques de sécurité |
/api/keys | GET | read | Lister toutes les clés |
/api/keys | POST | manage | Générer une nouvelle clé |
/api/keys/:id | GET | read | Obtenir les détails d'une clé |
/api/keys/:id/activate | POST | manage | Activer une clé en attente |
/api/keys/:id/rotate | POST | manage | Rotation de clé (nouvelle version) |
/api/keys/:id/revoke | POST | manage | Révoquer définitivement une clé |
/api/keys/:id/destroy | POST | manage | Détruire la matière de clé |
/api/keys/:id/encrypt | POST | encrypt | Chiffrer des données |
/api/decrypt | POST | encrypt | Déchiffrer des données |
/api/threat | GET | read | Détails sur les renseignements de menace |
/api/policies | GET | read | Politiques actives des clés |
/api/auth/whoami | GET | read | Informations sur la clé API courante |
/api/auth/keys | GET | admin | Lister les clés API |
/api/auth/keys | POST | admin | Créer une clé API |
/api/auth/keys/:id | DELETE | admin | Révoquer une clé API |
Root Key
└── Domain Key (par environnement / unité métier)
└── KEK — Key Encrypting Key (enveloppe les DEK)
└── DEK — Data Encrypting Key (chiffre les données applicatives)
Suit la norme NIST SP 800-57. Chaque niveau contient le rayon d'explosion d'une compromission — une DEK divulguée n'expose pas les autres DEK car la KEK est séparée.
| Portée | Permissions |
|---|---|
read | Voir les clés, statut, métriques, niveau de menace |
encrypt | Chiffrer et déchiffrer des données |
manage | Créer, faire rotation, révoquer, détruire des clés |
admin | Tout ce qui précède + gérer les clés API |
admin implique toutes les autres portées. Principe du moindre privilège : donnez aux tableaux de bord de surveillance read, aux services applicatifs read + encrypt, aux outils d'administration admin.
Citadel surveille les événements de sécurité et ajuste automatiquement les politiques de clés :
| Niveau | Déclencheur | Réponse |
|---|---|---|
| LOW | Opérations normales | Périodes cryptographiques standard |
| GUARDED | Anomalies mineures | Rotation légèrement plus serrée |
| ELEVATED | Schémas suspects | Calendriers de rotation compressés |
| HIGH | Indicateurs de menace actifs | Rotation forcée, limites d'utilisation réduites |
| CRITICAL | Sous attaque | Restrictions maximales |
Événements qui augmentent le niveau de menace : échec d'authentification, échecs de déchiffrement, schémas d'accès rapides, escalade manuelle. Le score diminue avec le temps.
| Composant | Algorithme | Norme |
|---|---|---|
| Encapsulation de clé (classique) | X25519 ECDH | RFC 7748 |
| Encapsulation de clé (post-quantique) | ML-KEM-768 | FIPS 203 |
| Chiffrement des données | AES-256-GCM | NIST SP 800-38D |
| Dérivation de clé | HKDF-SHA256 | NIST SP 800-56C |
Construction hybride : les deux secrets partagés sont concaténés et passés via HKDF. La sécurité est maintenue si soit X25519 soit ML-KEM-768 reste sécurisé.
version[1] || suite_kem[1] || suite_aead[1] || flags[1] || kem_ct_len[2] ||
x25519_ephemeral_pk[32] || mlkem768_ct[1088] || nonce[12] || aead_ct[variable]
Auto-descriptif, versionné, sans négociation (empêche les attaques par rétrogradation). Voir SPEC.md pour les spécifications complètes.