2011-09-02 20 views
6

Trabajo en algunas cosas de criptografía.Cómo generar de forma segura un IV para el cifrado AES CBC?

  • utilizo AES 256 con el modo CBC
  • utilizo OPENSSL

Soy consciente de las siguientes cosas (fuente = Wikipedia):

un vector de initalization debería ser:

  • Único: no se debe repetir para ningún mensaje cifrado con una clave determinada
  • impredecible: un atacante que observe cualquier número de mensajes y sus vías intravenosas no debería tener información para predecir el siguiente con probabilidad de éxito superior al 50% por bit (es decir, indistinguible de azar)

Mi pregunta es , ¿cómo generar de forma segura IV con OPENSSL y PHP? Sé que hay tal funcionalidad en lib mcrypt (http://fr2.php.net/manual/fr/function.mcrypt-create-iv.php)

No encontré nada para hacer esto con OPENSSL (generando IV único e impredecible).

+0

¿Está autenticando sus textos cifrados? –

Respuesta

5

Utilice openssl_random_pseudo_bytes (lo más preferible con el segundo parámetro establecido en una variable existente, que luego debe probar que se estableció en TRUE). Esto generará IV con características de aleatoriedad apropiadas.

$wasItSecure = false; 
$iv = openssl_random_pseudo_bytes(16, $wasItSecure); 
if ($wasItSecure) { 
    // We're good to go! 
} else { 
    // Insecure result. Fail closed, do not proceed. 
} 

Alternativamente, PHP 7 ofrece random_bytes() que es mucho más simple.

+1

¿Cómo determinar la longitud apropiada para IVs? – foochow

+2

Tenga en cuenta que el segundo parámetro opcional de openssl_random_pseudo_bytes es una referencia a una variable. Su valor es establecido por openssl cuando la cadena generada se considera "criptográficamente fuerte". Ver http://www.openssl.org/docs/crypto/RAND_bytes.html – dod

+1

Correcto. El segundo parámetro se pasa por referencia y después de que la llamada contiene verdadero solo si el algoritmo utilizado es criptográficamente fuerte. Vea mi respuesta a continuación con un ejemplo y uso adecuado. – techdude

2

Puede usar openssl_random_pseudo_bytes (len, & crypto_stron).

El primer parámetro es la longitud que desea en bytes. Si está utilizando esto para utilizarlo en uno de los métodos abiertos de SSL, puede usar la función openssl_cipher_iv_length (método) para obtener la longitud correcta del método utilizado.

El segundo parámetro, & crypto_strong, le permite pasar una variable booleana que se establecerá en verdadera o falsa dependiendo de si el algoritmo utilizado fue criptográficamente seguro. Luego puede verificar esta variable y manejarla correctamente si la variable vuelve a ser falsa. Nunca debería suceder, pero si lo hace, probablemente querrás saberlo.

Aquí es un ejemplo de uso adecuado:

$method = 'aes-256-cbc'; 
$ivlen = openssl_cipher_iv_length($method); 
$isCryptoStrong = false; // Will be set to true by the function if the algorithm used was cryptographically secure 
$iv = openssl_random_pseudo_bytes($ivlen, $isCryptoStrong); 
if(!$isCryptoStrong) 
    throw new Exception("Non-cryptographically strong algorithm used for iv generation. This IV is not safe to use."); 

Para obtener más información, véase:

1

Simplemente más cómodo para usar las mismas cosas que Thomas sujested:

private function genIv() 
{ 
    $efforts = 0; 
    $maxEfforts = 50; 
    $wasItSecure = false; 

    do 
    { 
     $efforts+=1; 
     $iv = openssl_random_pseudo_bytes(16, $wasItSecure); 
     if($efforts == $maxEfforts){ 
      throw new Exception('Unable to genereate secure iv.'); 
      break; 
     } 
    } while (!$wasItSecure); 

    return $iv; 
} 
Cuestiones relacionadas