PWR Capsula

Formularios con cifrado extremo a extremo (E2E). El frontend cifra cada campo con RSA-OAEP (WebCrypto API) antes del envio. El backend almacena los datos cifrados y solo los descifra bajo peticion explicita con la clave maestra. PHP puro, sin frameworks ni dependencias externas.

Instalacion

Capsula necesita el archivo PHP del backend y el JavaScript del frontend.

PHP (Backend)
require_once __DIR__ . '/core/capsula.php';
HTML (Frontend)
<script src="capsula.js"></script>

Requisitos minimos

  • PHP 7.4 o superior
  • Extension openssl para generacion de claves RSA
  • Navegador con soporte WebCrypto API (todos los navegadores modernos)
  • Permisos de escritura en datos/capsula/

Inicio rapido

Crea un formulario cifrado E2E en pocas lineas.

PHP
require_once 'core/capsula.php';

// Crear formulario con campos cifrados
$form = pwr_capsula_crear([
    'nombre' => 'Formulario de contacto',
    'campos' => ['nombre', 'email', 'mensaje']
]);

// Renderizar HTML del formulario
echo pwr_capsula_renderizar($form['id']);

Funciones

pwr_capsula_crear()

Crea un nuevo formulario cifrado. Genera el par de claves RSA y almacena la configuracion.

Firma
pwr_capsula_crear(array $config): array
ParametroTipoDescripcion
$configarrayConfiguracion: nombre (string), campos (array de nombres de campo), destino_email (opcional)

Retorna: array con ok, id, clave_publica.

pwr_capsula_renderizar()

Genera el HTML completo del formulario con el JavaScript de cifrado E2E incluido.

Firma
pwr_capsula_renderizar(string $formulario_id): string

Retorna: string con el HTML del formulario listo para insertar en la pagina.

pwr_capsula_recibir()

Recibe y almacena un envio cifrado. Los datos llegan cifrados con RSA-OAEP desde el frontend.

Firma
pwr_capsula_recibir(string $formulario_id): array

Retorna: array con ok, envio_id, mensaje.

pwr_capsula_listar_envios()

Lista todos los envios recibidos de un formulario (metadatos, sin descifrar contenido).

Firma
pwr_capsula_listar_envios(string $formulario_id): array

Retorna: array de envios con id, fecha, ip (sin contenido descifrado).

pwr_capsula_descifrar_envio()

Descifra un envio concreto usando la clave maestra. Solo se descifra bajo peticion explicita.

Firma
pwr_capsula_descifrar_envio(string $formulario_id, string $envio_id, string $clave_maestra): array
ParametroTipoDescripcion
$formulario_idstringID del formulario
$envio_idstringID del envio a descifrar
$clave_maestrastringClave privada RSA para descifrar

Retorna: array con ok y datos (array con los campos descifrados).

pwr_capsula_exportar()

Exporta todos los envios de un formulario descifrados en formato JSON o CSV.

Firma
pwr_capsula_exportar(string $formulario_id, string $clave_maestra, string $formato = 'json'): array
ParametroTipoDescripcion
$formulario_idstringID del formulario
$clave_maestrastringClave privada RSA
$formatostring'json' o 'csv'

Retorna: array con ok, contenido (string) y mime.

pwr_capsula_listar_formularios()

Lista todos los formularios creados con sus metadatos.

Firma
pwr_capsula_listar_formularios(): array

Retorna: array de formularios con id, nombre, campos, total_envios.

pwr_capsula_borrar_envio()

Elimina un envio concreto de un formulario.

Firma
pwr_capsula_borrar_envio(string $formulario_id, string $envio_id): array

Retorna: array con ok y mensaje.

pwr_capsula_info()

Devuelve informacion del modulo: version, total de formularios y envios.

Firma
pwr_capsula_info(): array

Retorna: array con version, total_formularios, total_envios, openssl_disponible.

Configuracion

Capsula almacena los formularios y envios en datos/capsula/. Cada formulario tiene su propio directorio con la configuracion, claves y envios.

Estructura de directorios
datos/capsula/
  {formulario_id}/
    config.json          // Nombre, campos, opciones
    clave_publica.pem    // Clave publica RSA (se envia al frontend)
    clave_privada.pem    // Clave privada RSA (solo backend)
    envios/
      {envio_id}.json    // Datos cifrados de cada envio
Importante: La clave privada RSA nunca debe ser accesible desde el navegador. Asegurate de que la carpeta datos/ no sea servida por el servidor web.

Ejemplos

Formulario de contacto completo

contacto.php
require_once 'core/capsula.php';

// Crear formulario (solo la primera vez)
$form = pwr_capsula_crear([
    'nombre' => 'Contacto',
    'campos' => ['nombre', 'email', 'telefono', 'mensaje']
]);

// Renderizar formulario HTML con cifrado E2E
echo pwr_capsula_renderizar($form['id']);

Recibir envio cifrado

recibir.php
require_once 'core/capsula.php';

$formulario_id = $_POST['formulario_id'] ?? '';
$resultado = pwr_capsula_recibir($formulario_id);

if ($resultado['ok']) {
    echo 'Envio recibido correctamente';
} else {
    echo 'Error: ' . $resultado['mensaje'];
}

Panel de administracion: ver envios descifrados

admin-envios.php
require_once 'core/capsula.php';

$formulario_id = 'abc123';
$clave_maestra = file_get_contents('datos/capsula/' . $formulario_id . '/clave_privada.pem');

// Listar envios
$envios = pwr_capsula_listar_envios($formulario_id);
foreach ($envios as $envio) {
    // Descifrar cada envio
    $datos = pwr_capsula_descifrar_envio($formulario_id, $envio['id'], $clave_maestra);
    if ($datos['ok']) {
        echo $datos['datos']['nombre'] . ' - ' . $datos['datos']['email'] . "\n";
    }
}

Exportar envios a CSV

PHP
require_once 'core/capsula.php';

$export = pwr_capsula_exportar('abc123', $clave_maestra, 'csv');
if ($export['ok']) {
    header('Content-Type: ' . $export['mime']);
    header('Content-Disposition: attachment; filename="envios.csv"');
    echo $export['contenido'];
}