Paso 12: SparkRandomNumberGenerator
Como comentamos en el paso anterior, el núcleo de la chispa debe tener la capacidad para generar vectores de inicialización y Nonces desafío. Esto requiere un algoritmo PRNG (generador de números pseudoaleatorio). Por suerte, la función de rand48 está disponible en libc.
Sin embargo, debe ser sembrada un PRNG con una semilla aleatoria. Es muy importante para esta semilla a ser impredecible y no se repiten durante un período razonable de tiempo. Si el atacante puede predecir nuestra semilla, pueden predecir los números al azar, que también significa que puede averiguar nuestro desafío Nonces y vectores de inicialización.
Por ejemplo, si usamos siempre la misma semilla para poner en marcha nuestro PRNG, entonces todo el atacante tiene que hacer es capturar cualquier mensaje cifrado y luego fuerza nuestra chispa para reiniciar. Después de que el atacante simplemente repite el mensaje capturado, hasta que la chispa llega el mismo número al azar que se utilizaron para construir el mensaje grabado, y estamos hackeados.
El uso de más de una semilla no resuelve el problema, b y c el mismo ataque descrito aún obras, si el atacante tiene la capacidad de reiniciar continuamente la chispa tantas veces como hay semillas previamente computadas.
Por esta razón siempre debemos mezclar nuestras semillas previamente computados con una verdadera fuente de entropía. Es fácil lo suficiente en un ordenador complejo grande, pero el núcleo de la chispa es demasiado simple que alguna verdadera entropía en su propia memoria, por lo que la entropía debe provenir de una fuente externa.
Hay dedicados dispositivos que puede suministrar esta entropía amplificando el ruido cuántico en una ensambladura de semiconductor parcial inverso o dedicada de fichas de seguridad, pero eso sería excesivo para este proyecto.
En su lugar podemos utilizar la entropía inherente a la velocidad con la que mover paquetes sobre una red, así como utilizando la entropía del tiempo cuando una solicitud es ser precesión.
Algoritmo de
Por lo tanto, el algoritmo utilizado por SparkRandomNumberGenerator para generar un número aleatorio es el siguiente:
La entropía utilizada para sembrar la función PRNG (seed48) se mezcla de 3 fuentes diferentes:
- rand48 se siembra con una de 65536 semillas previamente computadas de 48 bits, almacenadas en Flash externo. Cada vez que la chispa se reinicia, se utiliza la siguiente semilla. La rotación de semillas puede desactivarse comentando a ROTATE_SEED en SparkRandomNumberGenerator.h: 35.
- 5 veces (por defecto es 8.8.8.8) es hacer ping a un servidor de red especificada. Cada vez que ping se utiliza como una ronda de HMAC (Master_Key, ping_time). Los primeros 128 bits de HMAC resultante es la entropía adicional XORed con cada llamada a rand48. Entropía de la red encuentro etapa es responsable de un retraso bastante larga en la primera solicitud del núcleo de la chispa después de que inicie. Para desactivar esta etapa comente PING_TEST_SERVER en SparkRandomNumberGenerator.h: 34.
- El número aleatorio de 128 bits generado es XORed con los primeros 128 bits de HMAC (Master_key, Current_Timestamp). Hasta el momento en que se solicitó el número aleatorio se utiliza para entropía adicional.
Todo lo que necesitamos hacer ahora es guardar las semillas previamente computadas en Flash externo. Ver los pasos a seguir.