Agarrar la clave ChaCha20 del ariete

0

Hay varias otras publicaciones que hablan acerca de cómo agarrar una clave de un ram como

Mi pregunta es un poco diferente. Supongamos que tenemos la clave y, en una breve ventana, la utilizaremos para inicializar un cifrado (en este caso, ChaCha20) y luego borraremos la clave de la memoria (utilizando las mejores prácticas, memset, etc.) [* edit2]

Una vez que se inicializa el cifrado, ¿equivale eso a tener la clave en la memoria?

Específicamente, mirando el código de referencia ChaCha20: enlace

void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
{
  const char *constants;

  x->input[4] = U8TO32_LITTLE(k + 0);
  x->input[5] = U8TO32_LITTLE(k + 4);
  x->input[6] = U8TO32_LITTLE(k + 8);
  x->input[7] = U8TO32_LITTLE(k + 12);
  if (kbits == 256) { /* recommended */
    k += 16;
    constants = sigma;
  } else { /* kbits == 128 */
    constants = tau;
  }
  x->input[8] = U8TO32_LITTLE(k + 0);
  x->input[9] = U8TO32_LITTLE(k + 4);
  x->input[10] = U8TO32_LITTLE(k + 8);
  x->input[11] = U8TO32_LITTLE(k + 12);
  x->input[0] = U8TO32_LITTLE(constants + 0);
  x->input[1] = U8TO32_LITTLE(constants + 4);
  x->input[2] = U8TO32_LITTLE(constants + 8);
  x->input[3] = U8TO32_LITTLE(constants + 12);
}

Parece que uno simplemente necesita obtener la ubicación de la memoria apuntada por la entrada x- > leer como 48 bytes de datos desde ese punto, y lo tiene.

  1. ¿Esto es correcto?
  2. ¿Cómo se puede evitar esto en el software? (mejores prácticas)

EDITAR: veo que al menos la entrada [12] y la entrada [13] se ajustan a medida que se procesan los bytes ... y que el cifrado puede "buscarse" ajustando la entrada [8] y la entrada [9] (o al menos en salsa20, supongo que chacha20 es similar) ... por lo tanto, probablemente sería suficiente simplemente buscar una "ubicación" aleatoria, y cifrar algunos bytes de relleno aleatorios, al inicializar

  1. ¿Esto es correcto? ¿Mejoraría la defensa contra la obtención de la clave (o estado de inicialización)?

EDIT 2:

Creo que la clave se puede borrar de la memoria una vez que se inicializa el cifrado, ya que la implementación de referencia no la utiliza para descifrar ... ¿o me falta algo?

Ejemplo:

ECRYPT_init();
ECRYPT_keysetup(&ctx, MyKey, ECRYPT_MAXKEYSIZE, ECRYPT_MAXIVSIZE);
ECRYPT_ivsetup(&ctx, MyIv);

//notice neither MyKey nor MyIv are used here:
ECRYPT_decrypt_bytes(&ctx, ciphertext, plaintext, ciphertext_len);
    
pregunta davidkomer 16.06.2016 - 20:03
fuente

1 respuesta

1

El algoritmo ChaCha20 es tan simple que si tienes curiosidad acerca de cómo funciona, puedes escribir tu propia implementación (¡pero no utilizarla en producción!). RFC 7539 es una referencia simple que también viene con ejemplos para que pueda verificar la corrección a medida que avanza. Pero la forma en que funciona es que usted XOR el mensaje con un flujo de clave que se genera como un conjunto de bloques de 64 bytes, donde cada bloque es "nombrado" por tres argumentos :

  1. La clave (secreto);
  2. El nonce (no secreto);
  3. El contador de bloques (no secreto).

El bloque se inicializa con estos valores y algunas constantes en la forma en que se muestra el fragmento de código. Luego, el bloque se revuelve con la operación de doubleround diez veces (diez rondas dobles = veinte rondas, por eso hay un "20" en el nombre). Y ahora, críticamente, el estado inicial del bloque se agrega al resultado de eso, y este paso requiere la clave nuevamente, por lo que si lo borra, no podrá realizar este paso final.

Después de esa adición final, la clave no debería ser fácilmente recuperable del bloque resultante (¡o de lo contrario el cifrado está completamente roto!). Pero, sin embargo, el contenido del bloque es un secreto confidencial, porque un atacante que lo ve puede descifrar el bloque de texto cifrado correspondiente.

Sin embargo, todo lo que tiene en este punto es un bloque de 64 bytes, que solo sirve para cifrar o descifrar un bloque de 64 bytes del mensaje. A menos que 64 bytes sea la longitud de mensaje más grande que jamás cifrará, necesitará la clave una y otra vez para generar bloques adicionales. Por lo tanto, solo puede borrar la clave y los bloques después de haber cifrado o descifrado el mensaje completo.

Dado que tanto la clave como los bloques del flujo de clave son datos secretos, querrá utilizar las instalaciones de su sistema operativo para evitar que la memoria se intercambie en el disco. Y querrá poner a cero esa memoria de manera segura una vez que haya terminado con ella.

Se aplican consideraciones similares a otros cifrados, pero los detalles son diferentes. Por ejemplo, muchos sistemas de cifrado (pero no ChaCha20) tienen una programación de teclas , es decir, una secuencia de "subclaves" derivadas de la clave secreta. A menudo, es el caso de que después de haber generado la programación de claves ya no necesite la clave, por lo que podría poner a cero la clave en ese momento, pero las subclaves deben estar protegidas y usted debe aferrarse a ellos porque los reutiliza para cada bloque que procesa.

    
respondido por el Luis Casillas 17.06.2016 - 10:11
fuente

Lea otras preguntas en las etiquetas