2011-03-09 8 views
7

Estoy buscando una manera de encriptar/ofuscar (y por supuesto descifrar/desofuscar) una matriz de bytes usando .NET 3.5.¿Forma fácil de encriptar/ofuscar una matriz de bytes usando un secreto en .NET?

Básicamente:

byte[] aMixedUp = Encrypt(aMyByteData, "THIS IS THE SECRET KEY USED TO ENCRYPT"); 

y en el otro lado:

byte[] aDecrypted = Decrypt(aMixedUp, "THIS IS THE SECRET KEY USED TO ENCRYPT"); 

No tiene que ser a prueba de balas. La idea es solo evitar que los usuarios vean directamente lo que hay en los bytes en caso de que se asignen a ASCII, pero debería ser mejor que ROT13.

¿Hay algo en las librerías de .NET que pueda usar fácilmente?

+0

La manera más fácil que he encontrado es en [mi pregunta aquí] (http://stackoverflow.com/questions/11762/c-cryptographicexception-padding-is-invalid-and-cannot-be-removed) – Blorgbeard

+0

¿Entonces la conversión de base está fuera de cuestión? Digamos que la conversión a Base64 o incluso Base2? ¡Creo que es mejor que ROT13! – Ali

+1

@Blorgbeard: ¿Por qué no hacer que una respuesta, te doy crédito! ¡Eso es exactamente lo que he estado buscando! – Krumelur

Respuesta

7

Aquí hay un código que escribí para encriptar/desencriptar una cadena. La cadena cifrada está codificada en Base64 para facilitar la serialización en XML, etc. Puede convertir fácilmente este código para trabajar directamente con matrices de bytes en lugar de cadenas.

/// <summary> 
/// Create and initialize a crypto algorithm. 
/// </summary> 
/// <param name="password">The password.</param> 
private static SymmetricAlgorithm GetAlgorithm(string password) 
{ 
    var algorithm = Rijndael.Create(); 
    var rdb = new Rfc2898DeriveBytes(password, new byte[] { 
     0x53,0x6f,0x64,0x69,0x75,0x6d,0x20,    // salty goodness 
     0x43,0x68,0x6c,0x6f,0x72,0x69,0x64,0x65 
    }); 
    algorithm.Padding = PaddingMode.ISO10126; 
    algorithm.Key = rdb.GetBytes(32); 
    algorithm.IV = rdb.GetBytes(16); 
    return algorithm; 
} 


/// <summary> 
/// Encrypts a string with a given password. 
/// </summary> 
/// <param name="clearText">The clear text.</param> 
/// <param name="password">The password.</param> 
public static string EncryptString(string clearText, string password) 
{ 
    var algorithm = GetAlgorithm(password); 
    var encryptor = algorithm.CreateEncryptor(); 
    var clearBytes = Encoding.Unicode.GetBytes(clearText); 
    using (var ms = new MemoryStream()) 
    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(clearBytes, 0, clearBytes.Length); 
     cs.Close(); 
     return Convert.ToBase64String(ms.ToArray()); 
    } 
} 

/// <summary> 
/// Decrypts a string using a given password. 
/// </summary> 
/// <param name="cipherText">The cipher text.</param> 
/// <param name="password">The password.</param> 
public static string DecryptString(string cipherText, string password) 
{ 
    var algorithm = GetAlgorithm(password); 
    var decryptor = algorithm.CreateDecryptor(); 
    var cipherBytes = Convert.FromBase64String(cipherText); 
    using (var ms = new MemoryStream()) 
    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(cipherBytes, 0, cipherBytes.Length); 
     cs.Close(); 
     return Encoding.Unicode.GetString(ms.ToArray()); 
    } 
} 
+1

Como ya se dijo: ¡este es mi favorito! ¡Gracias! – Krumelur

3

Symmetric-key algorithm sería la forma más fácil de hacer esto, puede encontrarlos en .NET Framework.

Pero tenga en cuenta que un hacker puede "fácilmente" descompilar su aplicación y encontrar la clave de cifrado. Dependiendo de su senario puede usar un sistema de clave public/private. Al menos puede controlar quién puede encriptar la matriz de bytes.

4

La siguiente es una muestra de código que usa la clase Rijndael de .NET framework para cifrar y descifrar una matriz de bytes; obviamente, esta clase puede sustituirse por la que más le convenga.

Solo necesita definir las propiedades KEY e IV y obtenerlas de alguna parte (sección encriptada del archivo de configuración de la aplicación, por ejemplo).

private static byte[] EncryptBytes(IEnumerable<byte> bytes) 
    { 
     //The ICryptoTransform is created for each call to this method as the MSDN documentation indicates that the public methods may not be thread-safe and so we cannot hold a static reference to an instance 
     using (var r = Rijndael.Create()) 
     { 
      using (var encryptor = r.CreateEncryptor(KEY, IV)) 
      { 
       return Transform(bytes, encryptor); 
      } 
     } 
    } 

    private static byte[] DecryptBytes(IEnumerable<byte> bytes) 
    { 
     //The ICryptoTransform is created for each call to this method as the MSDN documentation indicates that the public methods may not be thread-safe and so we cannot hold a static reference to an instance 
     using (var r = Rijndael.Create()) 
     { 
      using (var decryptor = r.CreateDecryptor(KEY, IV)) 
      { 
       return Transform(bytes, decryptor); 
      } 
     } 
    } 

    private static byte[] Transform(IEnumerable<byte> bytes, ICryptoTransform transform) 
    { 
     using (var stream = new MemoryStream()) 
     { 
      using (var cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write)) 
      { 
       foreach (var b in bytes) 
        cryptoStream.WriteByte(b); 
      } 

      return stream.ToArray(); 
     } 
    } 
0

Si usted no necesita cifrado, sólo puede convertir todo para HEX o base 64 o algo por el estilo, de manera efectiva que va a hacer imposible leer a menos que alguien es realmente dedicado. Here is a link that shows how in .NET

+5

No creo que decodificar hexadecimal o base64 cuente como "realmente dedicado" .. – Blorgbeard

Cuestiones relacionadas