2010-04-17 23 views
56

¿Cuál es la diferencia entre usar Rfc2898DeriveBytes y simplemente usar Encoding.ASCII.GetBytes(string object);?¿Por qué necesito usar la clase Rfc2898DeriveBytes (en .NET) en lugar de usar directamente la contraseña como clave o IV?

He tenido un éxito relativo con cualquier enfoque, el primero es un enfoque más largo sin complicaciones, ya que este ú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 cifrado 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í.

Éstos son algunos ejemplos que le muestre dónde vengo:

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

o

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

El objeto 'rfcKey' ahora se puede utilizar para la creación de la .KEY o .IV propiedades 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 funcionar!

La parte confusa ... así que en lugar de usar 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?

+0

¡Esta pregunta está relacionada con la revisión y la preparación para el examen! – IbrarMumtaz

Respuesta

135

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 varias 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 debe realizar 1000 iteraciones hash para cada contraseña. 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 se distribuye 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.

+2

wow gracias por esto, buena respuesta. – IbrarMumtaz

+0

excelente respuesta - ¡gracias! –

+0

Esta respuesta ha sido muy útil. Aprendí algo nuevo hoy. Gracias. –

4

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, ver RFC2898

entiendo una pequeña parte:

con Encoding.ASCII.GetBytes(), cuando se utiliza una contraseña larga, que va a utilizar en la mayoría de los primeros bytes rj.KeySize de eso El resto 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).

+0

ahhh esto tiene sentido, cuando usamos el objeto rfc podemos especificar el tamaño de la matriz de bytes que se devolverá. Para asegurarnos de cumplir con la propiedad de tamaño de clave de los algoritmos. – IbrarMumtaz

Cuestiones relacionadas