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:
- Acceso normal: escribe
4821. Debe armar el sistema. - PIN incorrecto: escribe
1234. Debe registrar el fallo. - Ataque simulado: escribe tres PIN incorrectos seguidos. Debe bloquear. Intenta el PIN correcto durante el bloqueo: debe ignorarse.
- Alarma: con el sistema armado, activa el PIR. La alarma debe quedarse encendida.
- Desarmar: escribe
4821. La alarma debe apagarse. - 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.