o TRNG (True Random Number Generation)
La generación de números aleatorios (RNG) no se puede implementar con un algoritmo, a diferencia de PRNG que precisamente eran algoritmos con un parámetro o semilla que les permitía generar secuencias impredecibles
(impredecibles a condición de que no se conozca la semilla)
¿Cómo implementamos un RNG si no es algorítmico?
*) HSM: Hardware Secure Module
UI ($\ll 1$ kbps después de reducción)
latencia disco duro ($\ll 1$ kbps después de reducción)
red ($\approx 1$ kbps después de reducción)
funciones de procesador (Intel: $\gg$ Mbps)
Los RNG deben tener unas propiedades
estas propiedades no aplican al número generado (o el bit) en sí, si no a las secuencias de números generados
la secuencia de números (o de bits) debe tener una distribución uniforme
para $n$ bits generados, la probabilidad de una secuencia dada es la misma de la de cualquier otra ($2^{-n}$)
ningún algoritmo puede predecir el seguiente bit conocidos los anteriores (y además, la probabilidad de acierto debe ser $p \approx 1/2$)
para secuencias suficientemente largas el número de '$1$'s y '$0$'s tiende a ser el mismo
para secuencias suficientemente largas el número de grupos ${00, 01, 10, 11}$ tiende a ser el mismo
etc.
estos tipos de test permiten saber que mi fuente no tiene problemas obvios, pero no es suficiente contra un atacante capaz de modificar conveniente el sistema RNG
un RNG sólo se puede considerar seguro si sabemos como lo generamos, y lo generamos de forma segura
Wikipedia: Random number generator atack
Cloud: random... con poca entropía por poca I/O
Debian (Ubuntu): random... con poca entropía por errores de código
Intel: random... implementación cerrada (...)
PlayStation 3: random... constante
la criptografía es segura siempre que las hipótesis de funcionamiento se cumplan
la aleatoriedad suficiente de la fuente RNG (o PRNG) es una de ellas
(de xkcd.com/221)
¿para generar claves hemos de utilizar PRNG o RNG?
podemos usar PRNG a condición que:
AES-CTR
cifrando una secuencia constante es una buena opción)
AES-128
ó RSA-3072
)AES-256-CTR
si queremos generar claves con $256$ b de seguridad con una única
secuencia)(usados en HSM, SmartCards, algunas CPUs, etc.)
una resistencia a temperatura ambiente, tiene electrones libres que se mueven aleatoriamente (carga negativa) y podemos medir el desequilibrio momentáneo con un conversor Analógico/Digital
el conversor dará una secuencia indefinida de bits aleatorios
el ruido térmico es el resultado de un fenómeno caótico (no estrictamente aleatorio)
(…)
con una fuente (tenue) apuntamos a un espejo semireflectante; dos fotodetectores detectan uno u otro el fotón de forma totalment aleatoria
(d'idquantique.com)
las dos familias de dispositivos generan números aleatorios… pero no uniformes
el flujo en crudo se debe processar siempre, típicamente:
esto reduce los bps per "uniformiza" la secuencia
en Linux (Ubuntu) tenemos dos fuentes random:
/dev/random
: salida RNG basada en I/O ($\approx$ bps)/dev/urandom
: unblocking random, salida PRNG enriquecida con /dev/random
; ($\approx$ Mbps)en otros Linux tenemos diferentes combinaciones de /dev/random
y con aleatoriedad obtenida de diferentes fuentes
(Hardware Secure Module)
(Hardware Secure Module)
las funciones de un HSM son:
(fuente
DGP)
para implementar las funciones anteriores hace falta:
los HSM pueden ser certificados según
FIPS 140-2
en diferentes niveles:
este estándar define los requisitos de seguredad que deben seguir los HSM (certificados):
The security requirements cover areas related to the secure design and implementation of a cryptographic module. These areas include cryptographic module specification; cryptographic module ports and interfaces; roles, services, and authentication; finite state model; physical security; operational environment; cryptographic key management; electromagnetic interference/electromagnetic compatibility (EMI/EMC); self-tests; design assurance; and mitigation of other attacks.
para gestionar claves de usuarios para firma avanzada habitualmente se
requiere FIPS 140-2 nivel 2
para autoridades de validación o de sello de tiempo, habitualmente se
requiere FIPS 140-2 nivel 2
para autoridades de certificación habitualmente se
require FIPS 140-2 nivel 3
PKCS #11
es una especificación de la API de los HSM en lenguaje C (literalmente un .h
)
PKCS: Public Key Cryptographic Standard. Estándares de facto publicados por RSA Labs. Inc. (ahora EMC2 (ahora Dell Technologies));
actualmente la gestión del estándar ha pasado a
OASIS
en claves importantes (e.g. la de una CA raíz) un HSM puede no ser suficiente (¿y si lo roban?)
en estos casos podemos dividir la clave en trozos:
¿lo podemos hacer "por software"?
sí, pero el secreto ha estado "en claro" en la RAM del ordenador por tanto una vez recuperado el secreto su exposición ha aumentado notablemente
pero en HSM es una propiedad habitual
XOR
) entre los trozos de clave$n$ custodios se reparten la clave = $\{0,1\}^{\|n\|}$
partición${}_1$ = secuencia aleatoria de $n$ bits
partición${}_2$ = secuencia aleatoria de $n$ bits
…
partición${}_{n-1}$ = secuencia aleatoria de $n$ bits
partición${}_n$ = partición${}_1 \oplus \cdots \oplus$ partición${}_{n-1} \oplus$ clave
Es incondicionalmente seguro (criptográficamente hablando) pero "muy inseguro" desde el punto de vista de robustez funcional:
si se pierde un trozo/partición se pierde la clave sin remedio
permite dividir el secreto en $M$ trozos, de los cuales nos hacen falta $N$ para recuperarlos
definido sobre $(x \in \mathbb{Z}_{p}^{*}, y \in \mathbb{Z}_{p}^{*})$ (no sobre $(x \in \mathbb{R}, y \in \mathbb{R})$ como en el dibujo anterior)
si en lugar de utilizar una recta (polinomio de grado $1$), usamos un polinomio de grado $M-1$ podemos ajustar cuantos trozos se deben recuperar ($M$)
podemos dividirlo en tantos trozos ($N$) como haga falta ($N | N \geq M$)