Freedec: Secure Document & Password Recovery Service
🇪🇸 Leer en Español (Guía Completa para Principiantes) | 🇬🇧 Read in English (Complete Beginner-Friendly Guide)
🇪🇸 Español: Guía Completa de la Aplicación Freedec
Bienvenido a la documentación oficial de Freedec.
📑 Índice de Contenidos (Español)
- ¿Qué es Freedec y qué problema resuelve?
- Requisitos Previos del Sistema
- Entorno de Pruebas Rápido (Staging Sandbox sin tocar tu proyecto)
- Las 4 Opciones de Instalación en un Proyecto Existente
- Guía Paso a Paso de Integración (Línea por Línea)
- Cómo Funciona y Cómo se Usa la Web GUI (Navegador)
- Endpoints de la API REST (para Desarrolladores y cURL)
- Configuración de MEDIA en Producción (Nginx y Apache)
- Resolución de Problemas Frecuentes (FAQ / Troubleshooting)
1. ¿Qué es Freedec y qué problema resuelve?
Imagina que necesitas compartir un documento altamente confidencial (un contrato, una auditoría, unas credenciales maestras) con una lista específica de personas. Si envías el archivo y la contraseña por el mismo canal (por ejemplo, en el mismo correo o chat), cualquier persona que intercepte la comunicación tendrá acceso total.
Freedec resuelve esto mediante una arquitectura descentralizada de conocimiento cero (Zero-Knowledge) y verificación multi-factor:
- El Administrador sube el documento:
- El sistema calcula la huella digital exacta del archivo (hash SHA-256). No se usan IDs secuenciales (como
documento/1), lo que impide que atacantes adivinen URLs (anti-IDOR). - El archivo se cifra inmediatamente con AES-128-CBC + HMAC-SHA256 (Fernet) y se guarda protegido en disco.
- Se genera un Código Secreto de Acceso (
access_code) de 256 bits. El administrador recibe este código una sola vez para entregarlo en mano o por chat seguro (Signal/SMS). En la base de datos se guarda hasheado con PBKDF2 (incluso si roban la base de datos, nadie puede ver el código).
- El sistema calcula la huella digital exacta del archivo (hash SHA-256). No se usan IDs secuenciales (como
- El Destinatario recupera la clave:
- El usuario sube su copia del documento a la web de Freedec.
- Introduce el
access_codey su correo electrónico. - El sistema calcula el hash en tiempo real, verifica que posea el archivo original, comprueba el código y confirma que su correo esté en la lista blanca autorizada.
- La clave NUNCA se muestra en pantalla: se envía de forma automatizada y exclusiva al buzón del correo verificado.
2. Requisitos Previos del Sistema
Antes de empezar, comprueba que tienes instaladas estas herramientas en tu ordenador o servidor:
- Python 3.11 o 3.12:
Comprueba con:
python3 --version - Poetry (Gestor moderno de dependencias en Python):
Comprueba con:
poetry --versionSi no tienes Poetry instalado, instálalo en Linux/macOS con:curl -sSL https://install.python-poetry.org | python3 -
3. Entorno de Pruebas Rápido (Staging Sandbox)
El repositorio incluye un servidor de prueba autónomo preconfigurado. No necesitas tener ningún proyecto Django previo para probarlo.
Paso 1: Clonar e Instalar Dependencias
git clone https://github.com/jrubioh1/Freedec.git
cd Freedec
poetry install
Paso 2: Inicializar la Base de Datos de Prueba
Ejecuta el comando automatizado:
poetry run python manage.py setup_staging
Creará una base de datos SQLite local (db_staging.sqlite3), creará el usuario administrador admin con contraseña admin123 y generará un archivo de prueba legítimo sample_document.pdf.
Paso 3: Arrancar el Servidor
poetry run python manage.py runserver 8000
Paso 4: Probar la Interfaz Gráfica en tu Navegador
- Portal Público de Recuperación: Abre http://127.0.0.1:8000/freedec/ en tu navegador.
- Portal Público de Descifrado (.enc): Abre http://127.0.0.1:8000/freedec/descifrar/ en tu navegador.
- Panel de Administrador (Django Admin): Inicia sesión en http://127.0.0.1:8000/admin/ (usuario
admin, contraseñaadmin123) para cifrar y registrar documentos desde el menú Documentos Cifrados -> Añadir.
Paso 5: Probar el Flujo Automatizado por CLI (Opcional)
En otra terminal distinta, ejecuta:
poetry run python scripts/demo_flow.py
4. Las 4 Opciones de Instalación en un Proyecto Existente
Si ya tienes un proyecto Django funcionando, puedes incorporar freedec de cualquiera de estas 4 maneras:
Opción 1: Copiar la carpeta freedec/ a tu proyecto (La más sencilla y directa)
- ¿Qué se copia?: ÚNICAMENTE la carpeta
freedec/. - ¿Qué NO se copia?: NO copies
config/nimanage.py(tu proyecto ya tiene los suyos propios). - Comando para instalar dependencias:
En la carpeta de tu proyecto existente:
poetry add cryptography djangorestframework
Comparativa visual de directorios:
Tu Proyecto ANTES de copiar: Tu Proyecto DESPUÉS de copiar:
---------------------------- ------------------------------
mi_proyecto/ mi_proyecto/
├── manage.py ├── manage.py
├── mi_config/ ├── mi_config/
│ ├── settings.py │ ├── settings.py <-- Añadir 4 líneas
│ ├── urls.py │ ├── urls.py <-- Añadir 1 línea
│ └── wsgi.py │ └── wsgi.py
└── freedec/ <-- ¡Solo pegas esto!
├── models.py
├── views.py
├── templates/
└── ...
Opción 2: Como dependencia Git con Poetry (Ideal para repositorios en equipo)
Si Freedec está en un repositorio Git remoto (GitHub, GitLab):
poetry add git+https://github.com/jrubioh1/Freedec.git
Poetry clonará y gestionará las actualizaciones de Freedec como cualquier paquete estándar.
Opción 3: Enlace local editable con Poetry (Monorepos o Desarrollo Activo)
Si tienes el repositorio de Freedec descargado en tu misma máquina:
poetry add --editable /ruta/absoluta/a/Freedec
Cualquier cambio que hagas en el código de Freedec se reflejará al instante en tu proyecto principal.
Opción 4: Como paquete de PyPI o Registro Privado
Si compilas y publicas Freedec:
# En el repositorio Freedec:
poetry build
poetry publish
# En tu proyecto principal:
poetry add freedec
5. Guía Paso a Paso de Integración (Línea por Línea)
Sigue estos 6 pasos numerados en tu proyecto Django existente:
Paso 1: Generar la Clave Criptográfica Maestra
Abre tu terminal y ejecuta:
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Obtendrás una cadena de 44 caracteres base64 similar a:
2bXoO5W3uK_mZ6k9wE2qR7vA1yT8pI0uL4mN6jH3gD1=
Paso 2: Editar tu archivo settings.py
Abre el archivo settings.py de tu proyecto y añade lo siguiente:
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# 1. Añadir 'rest_framework' y 'freedec.apps.FreedecConfig' a INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Aplicaciones requeridas:
'rest_framework',
'freedec.apps.FreedecConfig',
]
# 2. Configurar la clave maestra que generaste en el Paso 1
# (En producción se recomienda inyectarla desde os.environ)
FREEDEC_FERNET_KEY = os.environ.get(
"FREEDEC_FERNET_KEY",
"Pega_Aqui_La_Clave_Generada_En_El_Paso_1=="
)
# 3. Tamaño máximo de archivo permitido (50 MB por defecto)
FREEDEC_MAX_FILE_SIZE = 50 * 1024 * 1024
# 4. Configurar las rutas de archivos MEDIA (si no las tenías)
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# 5. Configurar el correo (Usa tu SMTP habitual en producción)
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = 'no-reply@tudominio.com'
# 6. Throttling de seguridad en DRF (protege el endpoint público)
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
'DEFAULT_THROTTLE_RATES': {'anon': '5/minute'},
}
Paso 3: Editar tu archivo urls.py principal
Abre el archivo urls.py de la carpeta de configuración de tu proyecto y añade el include:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
# Acoplar las rutas de Freedec (GUI y API REST)
path('freedec/', include('freedec.urls', namespace='freedec')),
]
# Servir archivos multimedia únicamente durante desarrollo local:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Paso 4: Ejecutar las Migraciones
Ejecuta en tu terminal para crear las tablas en tu base de datos:
poetry run python manage.py makemigrations freedec
poetry run python manage.py migrate
Paso 5: Crear un Superusuario Administrador (si no tienes uno)
poetry run python manage.py createsuperuser
Introduce un nombre de usuario, correo y contraseña.
Paso 6: Iniciar tu Servidor
poetry run python manage.py runserver
¡Listo! Ya tienes tanto la interfaz web como la API REST plenamente operativas en tu proyecto.
6. Cómo Funciona y Cómo se Usa la Web GUI
Una vez acoplado, tendrás los portales web accesibles desde cualquier navegador:
A. Panel de Administración (Django Admin - http://localhost:8000/admin/)
- Inicia sesión con tu cuenta de administrador en
/admin/(o la ruta de admin de tu proyecto). - Entra al menú Documentos Cifrados -> Añadir Documento Cifrado.
- Selecciona tu documento en formato permitido (PDF, LibreOffice .odt/.ods o Microsoft Office .docx/.xlsx).
- Opcionalmente escribe una contraseña personalizada o déjalo vacío para que el sistema genere una automáticamente con alta entropía criptográfica (24 caracteres).
- Escribe las direcciones de correo autorizadas (usa el botón
➕ Añadir otro correopara agregar destinatarios de forma interactiva). - Pulsa Guardar.
- Resultado:
- Descarga Automática de Recibo de Credenciales: El navegador descargará al instante un archivo de texto
<nombre_original>_credenciales.txtcon el hash SHA-256, código secreto de acceso, contraseña y enlaces directos, para que el administrador pueda guardarlo de forma local sin que quede expuesto en claro en el servidor. - La pantalla mostrará el Código Secreto de Acceso (
access_code) con botón de copiado rápido y la Contraseña Asignada. - Un botón para descargar el archivo cifrado
<nombre_original>.enc.
- Descarga Automática de Recibo de Credenciales: El navegador descargará al instante un archivo de texto
B. Portal Público de Solicitud de Contraseña (http://localhost:8000/freedec/)
- El usuario final o destinatario entra a
http://localhost:8000/freedec/. - Sube su copia del documento (bien el archivo original o el archivo
.encque le facilitaron). - Pega el código de acceso facilitado por el emisor.
- Escribe su correo electrónico registrado en la lista de autorización.
- Pulsa Solicitar Contraseña.
- Resultado: La web mostrará un mensaje de confirmación neutro (anti-enumeración de usuarios). Si los datos son legítimos y el correo está autorizado:
- El sistema enviará de inmediato la contraseña al correo del destinatario, especificando explícitamente el nombre del documento al que corresponde la clave y un enlace directo a la pestaña de descifrado.
- El sistema registra el acceso en la tabla de auditoría (
DocumentAccessLog), actualizando el contadoraccess_count, la fecha de último acceso y la IP del solicitante.
C. Portal Público de Descifrado de Archivos .enc (http://localhost:8000/freedec/descifrar/)
¿Cómo se pasa del archivo .enc al documento original descifrado?
- El usuario abre
http://localhost:8000/freedec/descifrar/(o pulsa 🔓 Descifrar Archivo (.enc) en la barra de navegación). - Sube el archivo
.enc. - Pega la contraseña que acaba de recibir en su correo electrónico.
- Pulsa Descifrar y Descargar Archivo Original.
- Resultado: El sistema valida la contraseña en memoria, descifra el contenedor con AES-128/Fernet y descarga inmediatamente el archivo original con su nombre y extensión correcta (
documento.pdf,contrato.docx, etc.).
D. Eliminación de Documentos y Borrado Físico en Disco (Derecho al Olvido / GDPR)
Al eliminar un documento registrado:
- Señal
post_deleteautomática: Al borrar un documento desde el panel de Django Admin o el ORM, se elimina automáticamente su archivo físico.encasociado en disco para evitar archivos confidenciales huérfanos. - Botón directo en Django Admin: La tabla de documentos en
/admin/freedec/encrypteddocument/dispone de un botón directo🗑️ Eliminarpor cada fila. - Comando CLI de borrado:
# Listar documentos existentes poetry run python manage.py delete_document --list # Eliminar un documento específico por nombre o hash poetry run python manage.py delete_document balance_anual.pdf # Eliminar todos los registros y archivos físicos (.enc) poetry run python manage.py delete_document --all
E. Compatibilidad con Despliegues en Apache (Múltiples Apps en el Mismo Dominio)
Freedec está diseñado específicamente para convivir con otras aplicaciones en el mismo servidor Apache:
- Espacio de nombres aislado: Todas las rutas cuelgan de
/freedec/(ej.http://dominio.com/freedec/), sin invadir la raíz/ni rutas genéricas. - Resolución dinámica con SCRIPT_NAME: En las plantillas HTML se usa
{% url 'freedec:gui-public-request' %}y{% url 'freedec:gui-public-decrypt' %}, adaptándose automáticamente a subcarpetas comoWSGIScriptAlias /freedecoProxyPass. - Admin Desacoplado: Los recibos y enlaces al panel de administración se resuelven dinámicamente mediante
reverse('admin:index'), respetando la URL exacta que tu proyecto tenga configurada para Django Admin.
F. Descifrado por Terminal (Línea de Comandos CLI)
Para administradores, scripts o usuarios avanzados:
poetry run python manage.py decrypt_document ruta/al/archivo.enc --password "TuContraseña" --output documento_recuperado.pdf
7. Endpoints de la API REST
Si deseas integrar Freedec con un frontend en React, Vue, Angular o una app móvil, utiliza los endpoints REST:
1. Subida Administrativa (POST /freedec/api/admin/upload/)
- Headers:
Authorization: Bearer <TOKEN>o sesión activa. - Form-Data:
original_file: Archivo binario.plain_password: Contraseña.allowed_emails:["auditor@empresa.com"].
curl -X POST http://127.0.0.1:8000/freedec/api/admin/upload/ \
-u admin:admin123 \
-F "original_file=@documento.pdf" \
-F "plain_password=ClaveSecreta#2026!" \
-F 'allowed_emails=["auditor@empresa.com"]'
2. Recuperación Pública (POST /freedec/api/public/request-password/)
- Headers: Sin autenticación previa requerida (Público).
- Form-Data:
file: Archivo binario en posesión del usuario.access_code: Código secreto.email: Correo del usuario.
curl -X POST http://127.0.0.1:8000/freedec/api/public/request-password/ \
-F "file=@documento.pdf" \
-F "access_code=CODIGO_DE_ACCESO" \
-F "email=auditor@empresa.com"
8. Configuración de MEDIA en Producción (Nginx y Apache)
Opción A: Configuración en Nginx
Añade este bloque en tu archivo /etc/nginx/sites-available/tudominio:
server {
listen 443 ssl http2;
server_name tudominio.com;
# Servir la carpeta MEDIA directamente desde el disco:
location /media/ {
alias /var/www/tu_proyecto/media/;
autoindex off; # Desactiva listado de archivos
add_header X-Content-Type-Options "nosniff";
default_type application/octet-stream; # Fuerza descarga segura
location ~* \.(php|py|sh|pl|cgi|exe)$ { deny all; } # Bloquea scripts
}
# Resto de la aplicación Django (Gunicorn):
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Opción B: Configuración en Apache (httpd con mod_wsgi)
Añade estas líneas dentro de tu VirtualHost (/etc/apache2/sites-available/default-ssl.conf):
<VirtualHost *:443>
ServerName tudominio.com
# 1. Alias para servir la carpeta /media/ desde el disco
Alias /media/ /var/www/tu_proyecto/media/
<Directory /var/www/tu_proyecto/media>
Options -Indexes -FollowSymLinks
AllowOverride None
Require all granted
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
</IfModule>
<FilesMatch "\.(php|py|sh|pl|cgi|exe)$">
Require all denied
</FilesMatch>
ForceType application/octet-stream
</Directory>
# 2. Conexión con Django vía mod_wsgi
WSGIDaemonProcess tu_proyecto python-home=/var/www/tu_proyecto/.venv python-path=/var/www/tu_proyecto
WSGIProcessGroup tu_proyecto
WSGIScriptAlias / /var/www/tu_proyecto/config/wsgi.py
</VirtualHost>
9. Resolución de Problemas Frecuentes (FAQ)
¿Error: ImproperlyConfigured: Falta la configuración FREEDEC_FERNET_KEY?
- Causa: No has definido la clave maestra en tu
settings.py. - Solución: Genera una con
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"y colócala ensettings.py.
¿Error 404 al intentar descargar el archivo cifrado .enc?
- Causa en desarrollo: Falta la línea
urlpatterns += static(settings.MEDIA_URL, ...)en tuurls.py. - Causa en producción: No has configurado el alias
/media/en tu servidor Nginx o Apache.
¿No llega el correo con la contraseña al destinatario?
- Causa en desarrollo / sandbox por defecto: Tienes
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'. La contraseña se imprime en la terminal donde corre Django, no se envía por internet. - Solución: Configura tu servidor SMTP en un archivo
.enven la raíz (copiando.env.example). Dispones de plantillas para Gmail, Brevo, Outlook, etc. Puedes comprobar tu conexión SMTP al instante ejecutando:poetry run python manage.py test_smtp tu-correo@gmail.com
¿Qué sucede cuando elimino un registro de documento cifrado?
- Eliminación física garantizada: Gracias al receptor de señales
post_delete, cuando se elimina un registro (sea individualmente desde el Admin, por lotes o medianteQuerySet.delete()), el archivo físico.encasociado en disco (media_staging/encrypted_docs/) se destruye automáticamente del sistema de archivos, garantizando el cumplimiento de borrado seguro y GDPR.
¿Error: Tipo de archivo no permitido?
- Causa: Solo se admiten archivos PDF, LibreOffice (.odt, .ods, .odp, .odg) y MS Office (.docx, .xlsx, .pptx, .doc, .xls, .ppt). No se permiten archivos de texto plano
.txt, ejecutables.exeni scripts.sh.
🇬🇧 English: Complete Guide for Freedec Application
Welcome to the official documentation for Freedec.
📑 Table of Contents (English)
- What is Freedec and what problem does it solve?
- System Prerequisites
- Quick Test Sandbox (Staging mode without touching your project)
- The 4 Installation Options into an Existing Project
- Step-by-Step Integration Checklist (Line by Line)
- How the Web GUI Works and How to Use It
- REST API Endpoints (for Developers and cURL)
- Production MEDIA Configuration (Nginx & Apache)
- Frequently Asked Questions (FAQ / Troubleshooting)
1. What is Freedec and what problem does it solve?
Imagine you need to share a highly confidential document (a contract, an audit, master database credentials) with a specific list of recipients. If you send both the file and the password over the same channel (e.g. in the same email or chat), any attacker who intercepts the communication gains full access.
Freedec solves this through a decentralized Zero-Knowledge architecture and multi-factor verification:
- The Administrator uploads the document:
- The system computes the exact digital fingerprint of the file (SHA-256 hash). No sequential IDs (like
document/1) are used, completely preventing Insecure Direct Object References (anti-IDOR). - The file is encrypted immediately using AES-128-CBC + HMAC-SHA256 (Fernet) and securely saved to disk.
- A 256-bit Secret Access Code (
access_code) is generated. The administrator receives this code once to hand over in person or via secure channel (Signal/SMS). In the database, it is stored hashed with PBKDF2 (even if attackers dump the database, they cannot view the code).
- The system computes the exact digital fingerprint of the file (SHA-256 hash). No sequential IDs (like
- The Recipient retrieves the password:
- The user uploads their copy of the document to the Freedec web portal.
- Enters the
access_codeand their email address. - The system calculates the SHA-256 hash in real time, verifies possession of the exact file, checks the access code, and confirms their email is whitelisted.
- The password is NEVER shown on the screen: it is dispatched automatically and exclusively to the inbox of the verified email address.
2. System Prerequisites
Verify that your system has the following tools installed:
- Python 3.11 or 3.12:
Check with:
python3 --version - Poetry (Modern Python dependency manager):
Check with:
poetry --versionIf not installed, install it on Linux/macOS using:curl -sSL https://install.python-poetry.org | python3 -
3. Quick Test Sandbox (Staging Mode)
The repository provides a standalone preconfigured test server. You do not need an existing Django project to evaluate it.
Step 1: Clone and Install Dependencies
git clone https://github.com/jrubioh1/Freedec.git
cd Freedec
poetry install
Step 2: Initialize Test Database
Run the automated command:
poetry run python manage.py setup_staging
Creates a local SQLite database (db_staging.sqlite3), creates the superuser admin with password admin123, and generates a valid sample file sample_document.pdf.
Step 3: Start the Server
poetry run python manage.py runserver 8000
Step 4: Open the Web GUI in Your Browser
- Public Password Request Portal: Open http://127.0.0.1:8000/freedec/ in your browser.
- Public Document Decryption Portal (.enc): Open http://127.0.0.1:8000/freedec/descifrar/ in your browser.
- Admin Panel (Django Admin): Log in at http://127.0.0.1:8000/admin/ (
admin/admin123) to encrypt and register documents under Encrypted Documents -> Add.
Step 5: Run Automated CLI Demo (Optional)
In another terminal:
poetry run python scripts/demo_flow.py
4. The 4 Installation Options into an Existing Project
If you already have an existing Django project, you can integrate freedec in any of these 4 ways:
Option 1: Copy the freedec/ Folder (Simplest & Most Direct)
- What to copy?: ONLY the
freedec/folder. - What NOT to copy?: DO NOT copy
config/or rootmanage.py(your project already has its own). - Command to install requirements:
In your host project directory:
poetry add cryptography djangorestframework
Visual Directory Comparison:
Your Project BEFORE copying: Your Project AFTER copying:
---------------------------- ---------------------------
my_project/ my_project/
├── manage.py ├── manage.py
├── my_config/ ├── my_config/
│ ├── settings.py │ ├── settings.py <-- Add 4 lines
│ ├── urls.py │ ├── urls.py <-- Add 1 line
│ └── wsgi.py │ └── wsgi.py
└── freedec/ <-- Only copy this!
├── models.py
├── views.py
├── templates/
└── ...
Option 2: As a Direct Git Dependency via Poetry (Best for Teams)
poetry add git+https://github.com/jrubioh1/Freedec.git
Option 3: Local Editable Path via Poetry (Monorepos & Active Development)
poetry add --editable /absolute/path/to/Freedec
Option 4: Via PyPI or Private Package Registry
# In Freedec repository:
poetry build
poetry publish
# In your host project:
poetry add freedec
5. Step-by-Step Integration Checklist (Line by Line)
Follow these 6 numbered steps in your existing Django project:
Step 1: Generate Master Fernet Key
In your terminal:
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Step 2: Edit Your settings.py File
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# 1. Add 'rest_framework' and 'freedec.apps.FreedecConfig'
INSTALLED_APPS = [
# Existing apps...
'rest_framework',
'freedec.apps.FreedecConfig',
]
# 2. Configure master key generated in Step 1
FREEDEC_FERNET_KEY = os.environ.get("FREEDEC_FERNET_KEY", "YOUR_KEY_HERE==")
# 3. Maximum file size (default: 50 MB)
FREEDEC_MAX_FILE_SIZE = 50 * 1024 * 1024
# 4. MEDIA settings
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# 5. Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = 'no-reply@yourdomain.com'
# 6. DRF Rate Limiting
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
'DEFAULT_THROTTLE_RATES': {'anon': '5/minute'},
}
Step 3: Edit Your Main urls.py File
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('freedec/', include('freedec.urls', namespace='freedec')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Step 4: Run Database Migrations
poetry run python manage.py makemigrations freedec
poetry run python manage.py migrate
Step 5: Create Superuser (if needed)
poetry run python manage.py createsuperuser
Step 6: Start Your Server
poetry run python manage.py runserver
6. How the Web GUI Works and How to Use It
A. Admin Panel (Django Admin - http://localhost:8000/admin/)
- Log in at
/admin/(or your project's configured Django admin URL) with an administrator account. - Navigate to Encrypted Documents -> Add Encrypted Document.
- Select your document in an authorized format (PDF, LibreOffice .odt/.ods, or MS Office .docx/.xlsx).
- Optionally enter a custom decryption password, or leave it blank to automatically generate a cryptographically strong 24-character password.
- Enter authorized recipient emails (interactive
➕ Add another emailbutton available). - Click Save.
- Result:
- Automatic Credentials Receipt Download: The browser immediately downloads
<original_filename>_credenciales.txtcontaining the SHA-256 hash, secret access code, assigned password, authorized emails, and direct access links, allowing local storage without server plaintext persistence. - The screen displays the secret Access Code (
access_code) with quick-copy button and the Assigned Password. - A direct download button for the encrypted file
<original_filename>.enc.
- Automatic Credentials Receipt Download: The browser immediately downloads
B. Public Password Request Portal (http://localhost:8000/freedec/)
- The user navigates to
http://localhost:8000/freedec/. - Uploads their file copy (either the original file or the
.encencrypted container). - Pastes the secret access code provided by the issuer.
- Enters their authorized email address.
- Clicks Request Password.
- Result: A uniform, neutral confirmation message is displayed (preventing user or document enumeration). If the data matches and the email is authorized:
- The system immediately emails the password to the recipient, explicitly citing the document name and a direct link to the decryption portal.
- The access event is recorded in the
DocumentAccessLogaudit table, incrementingaccess_countand recording the last access timestamp and client IP.
C. Public Document Decryption Portal (http://localhost:8000/freedec/descifrar/)
How to turn the .enc file back into the original document?
- The user navigates to
http://localhost:8000/freedec/descifrar/(or clicks 🔓 Descifrar Archivo (.enc) in the navbar). - Uploads the
.encfile. - Pastes the password received in their email.
- Clicks Descifrar y Descargar Archivo Original.
- Result: The system decrypts the container in memory with Fernet and triggers an instant download of the original file with its exact name and extension (
document.pdf,contract.docx, etc.).
D. Document Deletion & Physical Disk Erasure (Right to Erasure / GDPR)
When deleting a registered document:
- Automated
post_deleteSignal: Deleting a record via Django Admin or ORM triggers automatic unlinking and physical deletion of the.encfile inMEDIA_ROOT. - Direct Admin Button: The document table at
/admin/freedec/encrypteddocument/provides an inline🗑️ Eliminarbutton on each row. - CLI Management Command:
# List existing documents poetry run python manage.py delete_document --list # Delete a specific document by name or hash poetry run python manage.py delete_document balance_anual.pdf # Delete all database records and physical (.enc) files poetry run python manage.py delete_document --all
E. Apache Deployment & Multi-App Compatibility (Same Domain)
Freedec is engineered to run seamlessly alongside other applications on the same Apache server:
- Isolated Namespace: All routes reside under
/freedec/(e.g.http://domain.com/freedec/), avoiding conflicts with the root domain/or other apps. - Dynamic Resolution with SCRIPT_NAME: HTML templates use
{% url 'freedec:gui-public-request' %}and{% url 'freedec:gui-public-decrypt' %}, adapting dynamically to subfolders (WSGIScriptAlias /freedecorProxyPass). - Decoupled Admin Integration: Receipts and links to Django admin dynamically use
reverse('admin:index'), respecting whatever admin URL the host project defines.
F. Command Line Decryption (CLI)
For system administrators, automated pipelines, or offline recovery:
poetry run python manage.py decrypt_document path/to/file.enc --password "YourPassword" --output recovered_document.pdf
7. REST API Endpoints
1. Admin Upload (POST /freedec/api/admin/upload/)
curl -X POST http://127.0.0.1:8000/freedec/api/admin/upload/ \
-u admin:admin123 \
-F "original_file=@document.pdf" \
-F "plain_password=SecretPassword#2026!" \
-F 'allowed_emails=["auditor@corp.com"]'
2. Public Password Request (POST /freedec/api/public/request-password/)
curl -X POST http://127.0.0.1:8000/freedec/api/public/request-password/ \
-F "file=@document.pdf" \
-F "access_code=SECRET_ACCESS_CODE" \
-F "email=auditor@corp.com"
8. Production MEDIA Configuration (Nginx & Apache)
Option A: Nginx Configuration
server {
listen 443 ssl http2;
server_name yourdomain.com;
location /media/ {
alias /var/www/your_project/media/;
autoindex off;
add_header X-Content-Type-Options "nosniff";
default_type application/octet-stream;
location ~* \.(php|py|sh|pl|cgi|exe)$ { deny all; }
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Option B: Apache Configuration (httpd / mod_wsgi)
<VirtualHost *:443>
ServerName yourdomain.com
Alias /media/ /var/www/your_project/media/
<Directory /var/www/your_project/media>
Options -Indexes -FollowSymLinks
AllowOverride None
Require all granted
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
</IfModule>
<FilesMatch "\.(php|py|sh|pl|cgi|exe)$">
Require all denied
</FilesMatch>
ForceType application/octet-stream
</Directory>
WSGIDaemonProcess your_project python-home=/var/www/your_project/.venv python-path=/var/www/your_project
WSGIProcessGroup your_project
WSGIScriptAlias / /var/www/your_project/config/wsgi.py
</VirtualHost>
9. Frequently Asked Questions (FAQ / Troubleshooting)
Error: ImproperlyConfigured: Falta la configuración FREEDEC_FERNET_KEY?
- Cause: Master key is missing in
settings.py. - Fix: Generate one via
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"and set it insettings.py.
404 Error downloading encrypted .enc file?
- In development: Missing
urlpatterns += static(settings.MEDIA_URL, ...)inurls.py. - In production: Missing
/media/alias in your Nginx or Apache configuration.
Password email not received?
- In default development / staging: You have
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'. Passwords print to the console terminal running Django. - Fix: Configure real SMTP credentials in a
.envfile (copying.env.example). You can test your SMTP delivery immediately with:poetry run python manage.py test_smtp your-email@gmail.com
What happens when an encrypted document record is deleted?
- Guaranteed Physical File Deletion: A
post_deletesignal listener guarantees that whenever anEncryptedDocumentrecord is deleted (from Django Admin single view, bulk actions, or ORMQuerySet.delete()), the underlying physical.encfile inmedia_staging/encrypted_docs/is immediately removed from disk for strict GDPR and privacy compliance.
Error: Tipo de archivo no permitido?
- Cause: Only PDF, LibreOffice (.odt, .ods, .odp, .odg), and MS Office (.docx, .xlsx, .pptx, .doc, .xls, .ppt) documents are allowed. Plain
.txt, executables.exe, and scripts.share rejected.
Release files for freedec 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| freedec-1.0.0.tar.gz | 88.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| freedec-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 186.5 kB
Release files / freedec-1.0.0.tar.gz
| Download URL | freedec-1.0.0.tar.gz |
|---|---|
| Size | 88.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb4994f66f6ec29ef97c1e4d4f43d6a3aef514c55462fc0c771e010527794eca
|
|
BLAKE2b-256 checksum How to use checksums |
feccc50af92af5701b14a344ae3044749f95226ba11e45540f2e016e45038199
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.14.7 Linux/7.2.6-gentoo-dist-hardened
|
Release files / freedec-1.0.0-py3-none-any.whl
| Download URL | freedec-1.0.0-py3-none-any.whl |
|---|---|
| Size | 98.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
60deb91c42284e9e0f613dacd77875812c0a6e45cb2ca11c1a0c027d6365062a
|
|
BLAKE2b-256 checksum How to use checksums |
b49d2c9151dec3d2018ae138bf7650d60687628047bcf32d868ba8e9ac5149a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.14.7 Linux/7.2.6-gentoo-dist-hardened
|