Mapa de la lección
Lección 19 publicada. Mapa, ejemplo, EX018.
flowchart TD
N0["Resultados de aprendizaje y conexión"]
N1["19.1 Primitivas"]
N2["19.2 Autenticar la telemetría"]
N3["19.3 Gestión de claves"]
N4["19.4 Identidad de personas y dispositivos"]
N5["19.6 Actividad práctica: Lab 8"]
N6["Síntesis del capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6
N6 --> EX["Ejemplo resuelto"]
EX --> Q["Ejercicio EX018"]
Dibujo lógico
flowchart LR
N0["Resultados de aprendizaje y conexión"]
N1["19.1 Primitivas"]
N2["19.2 Autenticar la telemetría"]
N3["19.3 Gestión de claves"]
N4["19.4 Identidad de personas y dispositivos"]
N5["19.6 Actividad práctica: Lab 8"]
N6["Síntesis del capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> Q["EX018"]
[Resultados de aprendizaje y conexión]
|
v
[19.1 Primitivas]
|
v
[19.2 Autenticar la telemetría]
|
v
[19.3 Gestión de claves]
|
v
[19.4 Identidad de personas y dispositivos]
|
v
[19.6 Actividad práctica: Lab 8]
|
v
[Síntesis del capítulo]
|
v
[Ejemplo resuelto] --> [Ejercicio EX018]
Resultados de aprendizaje y conexión
Al terminar este capítulo, usted podrá (1) explicar la criptografía simétrica y de clave pública, los hashes y los MAC, y elegir entre ellos; (2) diseñar la autenticación de mensajes con protección contra repeticiones para telemetría con recursos limitados; (3) planificar la gestión de claves (generación, distribución, almacenamiento, rotación, revocación) para una flota de campo; y (4) diseñar la identidad y la autenticación de personas y dispositivos. Se apoya en los capítulos 4, 13 y 18 y prepara los capítulos 27–28.
19.1 Primitivas
- Las funciones de hash (SHA-256, FIPS 180-4) transforman los datos en un resumen de tamaño fijo; encontrar colisiones o preimágenes debe ser inviable. Un hash por sí solo no autentica nada.
- El cifrado simétrico (AES, FIPS 197) usa una única clave compartida para la confidencialidad.
- Los códigos de autenticación de mensajes (HMAC, FIPS 198-1; RFC 2104) permiten a quienes poseen una clave compartida verificar que un mensaje no se ha alterado y que procede de un poseedor de la clave.
- La criptografía de clave pública, introducida por Diffie y Hellman (1976) y llevada a las firmas por Rivest, Shamir y Adleman (1978), usa pares de claves: cualquiera puede verificar una firma con la clave pública; solo quien posee la clave privada puede firmar.
- El cifrado autenticado (p. ej., AES-GCM) proporciona a la vez confidencialidad e integridad.
Nunca diseñe sus propias primitivas o protocolos cuando haya uno estándar que sirva; TLS 1.3 (RFC 8446) es la opción predeterminada para los enlaces IP que puedan ejecutarlo.
19.2 Autenticar la telemetría
Para un enlace con recursos limitados, un diseño habitual es: carga útil más un contador monótono (o una marca de tiempo), un MAC sobre ambos; el receptor comprueba el MAC en tiempo constante y después comprueba que el contador supere el último valor aceptado. El contador derrota la repetición; una marca de tiempo con una ventana de frescura derrota los ataques de retardo, pero necesita relojes sincronizados. Truncar HMAC-SHA256 a 128 bits es habitual para ahorrar ancho de banda, con un margen contra la falsificación reducido en proporción pero todavía muy grande. Persista el último contador o rote las claves al reiniciar; de lo contrario, un reinicio vuelve a abrir la puerta a la repetición (EX018).
19.3 Gestión de claves
Las claves son el punto donde la criptografía se encuentra con la operación. Decida: quién genera las claves y dónde (idealmente en hardware, nunca a mano); cómo llegan a los dispositivos (aprovisionamiento en fábrica, inscripción segura); dónde se almacenan (elementos seguros, no archivos de configuración); cómo rotan (de forma programada y tras una sospecha de compromiso); cómo se revocan; y quién puede acceder a ellas. Una clave por cada par de dispositivos limita el radio de impacto: comprometer una RTU no debe permitir a un atacante suplantar a otra. Una única clave para toda la flota es una causa común con $\beta \approx 1$ (capítulo 7).
19.4 Identidad de personas y dispositivos
Las personas necesitan cuentas nominativas, autenticación fuerte (multifactor resistente al phishing cuando sea posible; véase NIST SP 800-63B), roles asignados según las tareas y una baja inmediata cuando se van. Los dispositivos también necesitan identidades (certificados o claves aprovisionadas), para que una pasarela sepa con qué RTU está hablando. Las credenciales compartidas o predeterminadas son la falla de identidad más común en la TO. En el TMRP, los operadores usan cuentas nominativas con autenticación fuerte en los servidores SCADA, y cada RTU tiene su propia clave, de modo que la pasarela sabe qué estación envió cada mensaje.
19.5 Ejemplo resuelto: el formato de mensaje del TMRP (sintético)
El ADR-007 eligió HMAC con contadores. La trama del Lab 8 lleva un contador de 8 bytes, un ID de estación de 2 bytes, un nivel de 2 bytes y un HMAC-SHA256 truncado de 16 bytes: 28 bytes, de los cuales 22 son sobrecarga respecto de una carga útil sin autenticar de 6 bytes. Las claves por estación se generan en el elemento seguro de la pasarela durante la inscripción y se almacenan en el almacén de claves de la RTU; el lado SCADA las guarda en un módulo de seguridad de hardware. Las claves rotan anualmente y de inmediato ante una sospecha de compromiso; el contador se persiste en memoria no volátil cada 1.000 incrementos, con un salto hacia delante al reiniciar, de modo que la repetición de mensajes antiguos sigue siendo imposible.
19.6 Actividad práctica: Lab 8
# Lab 8 - authenticated telemetry with a counter: tamper and replay are rejected (synthetic key, offline)
import hmac, hashlib, struct
KEY = bytes.fromhex("00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff") # demo key only
def seal(ctr, station, level_cm):
body = struct.pack(">QHH", ctr, station, level_cm)
return body + hmac.new(KEY, body, hashlib.sha256).digest()[:16]
class Receiver:
def __init__(self): self.last = {}
def accept(self, msg):
body, tag = msg[:12], msg[12:]
if not hmac.compare_digest(tag, hmac.new(KEY, body, hashlib.sha256).digest()[:16]): return "reject: tag"
ctr, st, lvl = struct.unpack(">QHH", body)
if ctr <= self.last.get(st, -1): return "reject: replay"
self.last[st] = ctr; return f"ok st={st} ctr={ctr} level={lvl}cm"
r = Receiver(); m1, m2 = seal(1, 3, 312), seal(2, 3, 309)
forged = m2[:10] + struct.pack(">H", 150) + m2[12:]
for name, m in [("m1", m1), ("m2", m2), ("replay m1", m1), ("forged", forged)]: print(f"{name:10}", r.accept(m))
print("frame bytes:", len(m1), "overhead vs 6-byte payload:", len(m1) - 6)
Salida esperada:
m1 ok st=3 ctr=1 level=312cm
m2 ok st=3 ctr=2 level=309cm
replay m1 reject: replay
forged reject: tag
frame bytes: 28 overhead vs 6-byte payload: 22
La clave del laboratorio es un valor de demostración publicado; las claves reales nunca deben aparecer en el código fuente.
Los dos primeros mensajes de la estación tres se aceptan con contadores crecientes. La repetición del primer mensaje se rechaza porque su contador no es mayor que el último valor aceptado, y el mensaje falsificado, con su nivel cambiado de 309 a 150 centímetros, no supera la comprobación de la etiqueta. La última línea confirma el tamaño de trama usado en el ADR-007: veintiocho bytes, veintidós de ellos de sobrecarga. El laboratorio guarda el estado solo en memoria, y por eso el EX018 pregunta qué ocurre tras un reinicio.
19.7 Errores comunes y límites
- Usar hashes o CRC como si fueran MAC.
- Comparar etiquetas en un tiempo que no es constante.
- Perder la protección contra repeticiones al reiniciar.
- Claves compartidas por toda la flota; claves en archivos de configuración o en el código fuente.
- Contraseñas predeterminadas y cuentas compartidas.
- Decisiones criptográficas sin un plan para la vida útil del sistema (agilidad criptográfica).
El diseño del TMRP responde a cada punto: las etiquetas se comparan en tiempo constante, los contadores persisten entre reinicios, las claves son por estación y están en hardware seguro, y el formato de mensaje incorpora un identificador de suite para futuros cambios de algoritmo. Cada decisión tiene una prueba.
Ejercicios — capítulo 19
EX037 — Persistencia del contador. Objetivo: diseñar una protección contra repeticiones que resista los reinicios. Entradas: §19.5 (persistir cada 1.000 incrementos). Pasos: explique por qué la RTU debe saltar hacia delante al reiniciar y, como mínimo, cuánto; indique qué debe persistir el receptor. Evidencia esperada: explicación. Rúbrica: 3 = salto ≥ 1.000 más allá del último valor persistido para que ningún contador se reutilice, el receptor persiste el último aceptado por estación o rota las claves; 2 = solo un lado; 1 = vago; 0 = nada.
EX038 — Radio de impacto. Objetivo: comparar diseños de claves. Entradas: 42 estaciones de campo; opción A, una clave para toda la flota; opción B, una clave por estación. Pasos: compare la consecuencia de extraer una clave de una RTU robada, el esfuerzo de rotación tras ese robo y el almacenamiento necesario en el SCADA. Evidencia esperada: tabla y recomendación. Rúbrica: 3 = A permite al ladrón falsificar cualquier estación y obliga a rotar en toda la flota; B limita la falsificación a una estación con una sola rotación; almacenamiento trivial; recomendación B; 2 = falta una dimensión; 1 = recomendación sin razonamiento; 0 = nada.
Síntesis del capítulo
Elija primitivas estándar para la propiedad que necesite: hashes para las huellas, MAC o firmas para la autenticidad, cifrado autenticado para la confidencialidad con integridad. Añada frescura para derrotar la repetición y consérvela entre reinicios. La gestión de claves es el verdadero sistema: claves por dispositivo en hardware, rotación y revocación. Dé a las personas y a los dispositivos identidades distintas y con autenticación fuerte.