visual studio encriptacion cipher c# .net vb.net cryptography rijndael

c# - studio - ¿Cómo generar Rijndael KEY y IV usando una frase de contraseña?



encriptacion aes c# (5)

¿Cómo generar Rijndael KEY y IV usando una frase de contraseña? La longitud de la clave debe estar en 256 bits.


Creo que estás buscando una derivación de clave basada en contraseña. Hay Rfc2898DeriveBytes clase Rfc2898DeriveBytes que lo implementa.

Rfc2898DeriveBytes toma una contraseña, una sal y un conteo de iteraciones, y luego genera claves mediante llamadas al método GetBytes .

RFC 2898 incluye métodos para crear una clave y un vector de inicialización (IV) a partir de una contraseña y una sal. Puede usar PBKDF2, una función de derivación de clave basada en contraseña, para derivar claves utilizando una función pseudoaleatoria que permite generar claves de una longitud prácticamente ilimitada. La clase Rfc2898DeriveBytes se puede usar para producir una clave derivada a partir de una clave base y otros parámetros. En una función de derivación de clave basada en contraseña, la clave base es una contraseña y los otros parámetros son un valor saliente y un recuento de iteraciones.

Para obtener más información acerca de PBKDF2, consulte RFC 2898, "PKCS # 5: Especificación de criptografía basada en contraseña versión 2.0".

Ejemplo:

public static byte[] CreateKey(string password) { var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 }; const int Iterations = 9872; using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations)) return rfc2898DeriveBytes.GetBytes(32); }

Puedes usar DeriveBytes en cualquier algoritmo simétrico, no solo en Rijndael .
Ejemplo:

public static SymmetricAlgorithm InitSymmetric(SymmetricAlgorithm algorithm, string password, int keyBitLength) { var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 }; const int Iterations = 234; using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations)) { if (!algorithm.ValidKeySize(keyBitLength)) throw new InvalidOperationException("Invalid size key"); algorithm.Key = rfc2898DeriveBytes.GetBytes(keyBitLength / 8); algorithm.IV = rfc2898DeriveBytes.GetBytes(algorithm.BlockSize / 8); return algorithm; } } private static byte[] Transform(byte[] bytes, Func<ICryptoTransform> selectCryptoTransform) { using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, selectCryptoTransform(), CryptoStreamMode.Write)) cryptoStream.Write(bytes, 0, bytes.Length); return memoryStream.ToArray(); } }

Uso:

public static void Main() { using (var rijndael = InitSymmetric(Rijndael.Create(), "TestPassword", 256)) { var text = "Some text to encrypt"; var bytes = Encoding.UTF8.GetBytes(text); var encryptedBytes = Transform(bytes, rijndael.CreateEncryptor); var decryptedBytes = Transform(encryptedBytes, rijndael.CreateDecryptor); var decryptedText = Encoding.UTF8.GetString(decryptedBytes); Debug.Assert(text == decryptedText); } }

Asegúrese de cambiar los parámetros de salt e iterations .


El IV debe ser aleatorio (no necesita ser aleatorio impredecible, lo suficientemente aleatorio como para que no se reutilice).

En cuanto a generar la clave a partir de la contraseña, está buscando una función de derivación de clave para la cual actualmente hay al menos tres buenas opciones (PBKDF2, bcrypt, scrypt), utilizando un hash no iterado ya que un póster anterior sugiere que la mayoría de las veces conduce a sistemas inseguros.

También use AES o Rijndael, eso no es exactamente lo mismo. Usar una combinación de Rijndael que no sea parte de AES podría ser una pesadilla de interoperabilidad más adelante, y la seguridad de la combinación de esas funciones no se ha estudiado bien de todos modos.


Este es el código plug and play que encontré en internet. Simplemente funciona:

using System.IO; using System.Security.Cryptography; private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c }; public static byte[] Encrypt(byte[] plain, string password) { MemoryStream memoryStream; CryptoStream cryptoStream; Rijndael rijndael = Rijndael.Create(); Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); rijndael.Key = pdb.GetBytes(32); rijndael.IV = pdb.GetBytes(16); memoryStream = new MemoryStream(); cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(plain, 0, plain.Length); cryptoStream.Close(); return memoryStream.ToArray(); } public static byte[] Decrypt(byte[] cipher, string password) { MemoryStream memoryStream; CryptoStream cryptoStream; Rijndael rijndael = Rijndael.Create(); Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); rijndael.Key = pdb.GetBytes(32); rijndael.IV = pdb.GetBytes(16); memoryStream = new MemoryStream(); cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write); cryptoStream.Write(cipher, 0, cipher.Length); cryptoStream.Close(); return memoryStream.ToArray(); }


IV debe ser aleatorio (generalmente lo pasa junto con los datos encriptados), y la clave se puede derivar de varias maneras: simplemente agregue la contraseña a la longitud de la clave (si la contraseña es menor de 32 caracteres) o ( que es más confiable) derivar una clave usando el algoritmo hash SHA2 o usar alguna forma más sofisticada.


Use esta Clase Rfc2898DeriveBytes .

Un consejo, sin embargo, su nivel de seguridad ha disminuido / limitado por la longitud / fuerza de la frase de contraseña. Entonces, no lo hagas