Proyecto final: caja de acceso seguro

Une PIN con hash, bloqueo por intentos, alarma con PIR y registro de eventos en un solo sistema de acceso.

Qué vas a construir

Una caja de acceso seguro que combina las clases anteriores:

  • Un PIN guardado como hash (Guardar contraseñas como hash).
  • Bloqueo de 10 segundos tras 3 intentos fallidos (Fuerza bruta: por qué importan los intentos y el bloqueo).
  • Una alarma con sensor PIR, enclavada, que solo se apaga al desarmar (Alarma con sensor de movimiento PIR).
  • Un registro de eventos con marca de tiempo (Registro de eventos con marca de tiempo).

Lo que aprendes

  • Cómo combinar varias defensas en un mismo sistema.
  • Por qué cada defensa cubre un objetivo distinto: confidencialidad, disponibilidad e integridad.
  • Cómo probar un sistema con casos normales y casos de ataque.

Idea clave

Ninguna defensa es suficiente por sí sola. Un hash protege el PIN si alguien ve el código, pero no evita que alguien pruebe PIN sin límite. El bloqueo limita los intentos, pero no sirve si nadie revisa qué pasó. El registro deja huella, pero no detiene nada. Juntas, las tres capas hacen que un ataque sea más lento, más visible y más difícil.

Materiales en Tinkercad

  • Arduino Uno R3
  • Sensor PIR
  • 1 LED rojo (alarma) con resistencia de 220 Ω
  • Monitor serie

Paso 1: Diseño

Antes de programar, dibuja en tu cuaderno un diagrama con las cuatro partes y escribe qué objetivo protege cada una. Usa esta tabla:

Defensa Objetivo que protege
PIN con hash Confidencialidad
Bloqueo por intentos Disponibilidad del acceso
Alarma enclavada Integridad del espacio
Registro de eventos Auditoría

Paso 2: Código

El hash del PIN 4821 es 2088405012, el mismo de Guardar contraseñas como hash.

const int PIR = 4;
const int ALARMA = 8;
const int MAX_INTENTOS = 3;
const unsigned long ESPERA = 10000;
const unsigned long HASH_PIN = 2088405012UL;

bool armado = false;
bool alarmaActiva = false;
int fallos = 0;
unsigned long bloqueadoHasta = 0;

unsigned long hashDe(String texto) {
  unsigned long h = 5381;
  for (unsigned int i = 0; i < texto.length(); i++) {
    h = h * 33 + texto.charAt(i);
  }
  return h;
}

void registrar(String tipo, String detalle) {
  Serial.print("[");
  Serial.print(millis() / 1000);
  Serial.print(" s] ");
  Serial.print(tipo);
  Serial.print(": ");
  Serial.println(detalle);
}

void setup() {
  Serial.begin(9600);
  pinMode(PIR, INPUT);
  pinMode(ALARMA, OUTPUT);
  registrar("INICIO", "sistema listo");
}

void loop() {
  if (Serial.available()) {
    String intento = Serial.readStringUntil('\n');
    intento.trim();

    if (millis() < bloqueadoHasta) {
      registrar("BLOQUEO", "intento ignorado");
    } else if (hashDe(intento) == HASH_PIN) {
      fallos = 0;
      armado = !armado;
      alarmaActiva = false;
      registrar("ACCESO", armado ? "armado" : "desarmado");
    } else {
      fallos++;
      registrar("PIN", "incorrecto");

      if (fallos >= MAX_INTENTOS) {
        bloqueadoHasta = millis() + ESPERA;
        fallos = 0;
        registrar("BLOQUEO", "10 s por demasiados intentos");
      }
    }
  }

  if (armado && !alarmaActiva && digitalRead(PIR) == HIGH) {
    alarmaActiva = true;
    registrar("ALARMA", "movimiento detectado");
  }

  digitalWrite(ALARMA, alarmaActiva ? HIGH : LOW);
}

Paso 3: Pruebas

Ejecuta cada caso y anota el resultado en tu cuaderno:

  1. Acceso normal: escribe 4821. Debe armar el sistema.
  2. PIN incorrecto: escribe 1234. Debe registrar el fallo.
  3. Ataque simulado: escribe tres PIN incorrectos seguidos. Debe bloquear. Intenta el PIN correcto durante el bloqueo: debe ignorarse.
  4. Alarma: con el sistema armado, activa el PIR. La alarma debe quedarse encendida.
  5. Desarmar: escribe 4821. La alarma debe apagarse.
  6. Revisión: lee el registro completo. ¿Puedes reconstruir qué pasó y en qué orden?

Cómo sabes que lo lograste

  • Las seis pruebas dan el resultado esperado.
  • El PIN no aparece en el código.
  • El registro muestra cada evento con su marca de tiempo.
  • Puedes explicar qué objetivo protege cada defensa.

Rúbrica de evaluación

Criterio Peso Qué mirar
Funcionamiento 40 % Las seis pruebas del paso 3
Seguridad 25 % PIN con hash, bloqueo activo, alarma enclavada
Código 20 % Funciones claras, nombres descriptivos, sin PIN en texto claro
Explicación 15 % Tabla del paso 1 completa y justificada

Qué salió mal

El bloqueo no se activa. Revisa que ESPERA esté en milisegundos y que fallos se incremente solo en el caso de PIN incorrecto.

La alarma se apaga sola. Revisa que alarmaActiva solo se cambie a false al armar o desarmar.

El hash no coincide. Revisa que hashDe() sea idéntica a la de Guardar contraseñas como hash.

Siguiente clase

Esta es la última clase de la serie de ciberseguridad. Como siguiente paso, puedes proponer otra defensa para este sistema y explicar qué objetivo protegería.