¿Por qué necesito usar la clase Rfc2898DeriveBytes (en .NET) en lugar de usar directamente la contraseña como clave o IV?

¿Cuál es la diferencia entre usar Rfc2898DeriveBytes y simplemente usar Encoding.ASCII.GetBytes(string object); ?

He tenido un éxito relativo con cualquiera de los enfoques, el primero es un enfoque más largo sin fin, ya que el último es simple y al grano. Ambos parecen permitirte hacer lo mismo al final, pero estoy luchando para ver el punto en el uso del primero sobre el último.

El concepto básico que he podido comprender es que puedes convertir contraseñas de cadenas en matrices de bytes para usar, por ejemplo, en una clase de encriptación simétrica, AesManaged . A través de la clase de RFC, pero puedes usar valores de sal y contraseña cuando creas tu objeto rfc. Supongo que es más seguro, pero aún así es una conjetura inculta en el mejor de los casos! También te permite devolver matrices de bytes de un cierto tamaño, bueno, algo así.

Aquí hay algunos ejemplos para mostrarle de dónde vengo:

 byte[] myPassinBytes = Encoding.ASCII.GetBytes("some password"); 

o

 string password = "P@%5w0r]>"; byte[] saltArray = Encoding.ASCII.GetBytes("this is my salt"); Rfc2898DeriveBytes rfcKey = new Rfc2898DeriveBytes(password, saltArray); 

El objeto ‘rfcKey’ ahora se puede usar para configurar las propiedades .Key o .IV en una clase de algoritmo de cifrado simétrico.

es decir.

 RijndaelManaged rj = new RijndaelManaged (); rj.Key = rfcKey.Getbytes(rj.KeySize / 8); rj.IV = rfcKey.Getbytes(rj.Blocksize / 8); 

¡’rj’ debería estar listo para comenzar!

La parte confusa … entonces, en lugar de utilizar el objeto ‘rfcKey’, ¿no puedo usar mi matriz ‘myPassInBytes’ para ayudar a configurar mi objeto ‘rj’?

He intentado hacer esto en VS2008 y la respuesta inmediata es NO. ¿Pero ustedes tienen una mejor respuesta educada en cuanto a por qué la clase de RFC se utiliza sobre la otra alternativa que he mencionado anteriormente?

Realmente, realmente no desea utilizar una contraseña de usuario directamente como una clave de cifrado, especialmente con AES.

Rfc2898DeriveBytes es una implementación de PBKDF2. Lo que hace es repetir hash la contraseña del usuario junto con la sal. Esto tiene múltiples beneficios:

En primer lugar, puede usar contraseñas de tamaño arbitrario: AES solo admite tamaños de clave específicos.

En segundo lugar, la adición de la sal significa que puede usar la misma frase de contraseña para generar múltiples claves diferentes (suponiendo que la sal no es una constante, como lo es en su ejemplo). Esto es importante para la separación de llaves; Reutilizar claves en diferentes contextos es una de las formas más comunes en que se rompen los sistemas criptográficos.

Las iteraciones múltiples (1000 de forma predeterminada) ralentizan los ataques de adivinación de contraseñas. Considere a alguien que está intentando adivinar su clave AES. Si acaba de utilizar la contraseña, esto sería sencillo: simplemente pruebe con cada contraseña posible como la clave. Por otro lado, con PBKDF2, el atacante primero tiene que realizar 1000 iteraciones de hash para cada contraseña adivinada. Entonces, si bien ralentiza un poco al usuario, tiene un efecto desproporcionado en un atacante. (De hecho, es bastante común usar conteos de iteración mucho más altos, se recomienda generalmente 10000).

También significa que la clave de salida final está distribuida uniformemente. Si utilizó la contraseña, por ejemplo, típicamente 16 de 128 bits de la clave serían 0 (el bit ASCII alto). Eso inmediatamente hace que la búsqueda de claves sea 65536 veces más fácil de lo que debería ser, incluso ignorando la adivinación de contraseñas.

Finalmente, AES tiene vulnerabilidades específicas con ataques clave relacionados. Los ataques de clave relacionados son posibles cuando un atacante conoce algunos datos cifrados con varias claves, y existe alguna relación conocida (o adivinada) entre ellos. Por ejemplo, si cifró datos con una clave de contraseña de “Mi clave AES es una succión” (16 bytes, para AES-128) y con “MI AES KEY SUCKS”, podría ser posible un ataque de clave relacionado. Los ataques actualmente mejor conocidos no permiten realmente romper el AES completo de esta manera, pero se han ido mejorando progresivamente con el tiempo: la semana pasada se publicó un nuevo ataque que rompe 13 rondas (de un total de 14) de AES-256 usando un ataque clave relacionado. Sería profundamente imprudente confiar en que tales ataques no mejoran con el tiempo.

Respuesta corta: es más seguro. Por la misma razón, también hay un generador aleatorio especial en el espacio de nombres System.Security.

Para más detalles, vea RFC2898

Yo entiendo una pequeña parte:

con Encoding.ASCII.GetBytes (), cuando use una contraseña larga, usará como máximo los primeros bytes rj.KeySize de la misma. El rest es ignorado. Y cuando su contraseña sea más corta que el tamaño de la clave, tendrá que agregar relleno (y solo agregar una secuencia de 0 aumenta la vulnerabilidad).