none
Encriptar imagen y desencriptar solo para visualizar C# RRS feed

  • Pregunta

  • Hola que tal es la primera vez que entro aquí y necesito ayuda lo que quiero hacer es encriptar una imagen y almacenarla,

    para después visualizarla desde un pixturebox, obviamente desencriptando la imagen sin almacenarla,

    me gustaría un poco de su ayuda porfabor.

    encontre este codigo funciona encriptando almacenando y desencriptando almacenando

    pero lo que quiero hacer es desencriptar y visualizar en picturebox sin almacenar

    public static void EncryptFile(string inputFile, string outputFile)
            {
                try
                {
                    string password = @"myKey123"; // Your Key Here
                    UnicodeEncoding UE = new UnicodeEncoding();
                    byte[] key = UE.GetBytes(password);
                    string cryptFile = outputFile;
                    FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
                    RijndaelManaged RMCrypto = new RijndaelManaged();
                    CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write);
                    FileStream fsIn = new FileStream(inputFile, FileMode.Open);
                    int data;
                    while ((data = fsIn.ReadByte()) != -1)
                        cs.WriteByte((byte)data);
                    fsIn.Close();
                    cs.Close();
                    fsCrypt.Close();
                }
                catch (Exception E)
                {
                }
            }

            public void DecryptFile(string inputFile, string outputFile)
    {
        {
            string password = @"myKey123"; // Your Key Here
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] key = UE.GetBytes(password);
            FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
            RijndaelManaged RMCrypto = new RijndaelManaged();
            CryptoStream cs = new CryptoStream(fsCrypt,RMCrypto.CreateDecryptor(key, key),CryptoStreamMode.Read);            
            FileStream fsOut = new FileStream(outputFile, FileMode.Create);
            int data;
            while ((data = cs.ReadByte()) != -1)
            fsOut.WriteByte((byte)data);
            fsOut.Close();
            cs.Close();
            fsCrypt.Close();
        }
       }

    • Editado EduardoAva jueves, 7 de marzo de 2019 23:47
    jueves, 7 de marzo de 2019 23:00

Todas las respuestas

  • primero creo que la forma un poco chapusera pero muy buena es cambiarle el encbezado a los ficheros, cada fichero tiene encabesados y esto en sistemas operativos basados en unix se utiliza para determinar el tipo de fichero... ejemplo, en win cambias la extension jpg por exe pero no puedes ejecutarla, ahora este mismo fichero lo copias en linux y muestra la imagen pq lee el la cabecera... googlea sobre esto y veras q es una de las obciones buenas para eso.
    jueves, 7 de marzo de 2019 23:31
  • realizando unos cambios creando este codigo

    public static string DecryptFile2(string inputFile)
    {
                string password = @"myKey123"; // Your Key Here
                string decoded = string.Empty;
                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password);
        {
                    using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
                    {
                        using (RijndaelManaged RMCrypto = new RijndaelManaged())
                        {
                            CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read);
                            using (MemoryStream ms = new MemoryStream())
                            {
                                int data;
                                while ((data = cs.ReadByte()) != -1)
                                    ms.WriteByte((byte)data);

                                if (ms.CanSeek)
                                    ms.Seek(0, SeekOrigin.Begin);
                                
                                decoded = UE.GetString(ms.ToArray());
                            }
                        }
                    }
        }
                return decoded;
       }

    nose si funcione 

    ahora mi duda es como agregarlo al picturebox

    viernes, 8 de marzo de 2019 6:42
  • nose si funcione 

    Sí, esa es la idea correcta: sustituir el FileStream por un MemoryStream y eso deja el contenido descifrado en memoria sin crear un archivo en disco. No sé si todo el código es perfectamente correcto, pero si tiene algún pequeño errorcillo solo es cuestión de corregirlo. La idea básica es correcta.

    ahora mi duda es como agregarlo al picturebox

    Para usarlo, tienes que prescindir de esta línea (y modificar en consonancia el resto de la subrutina):

    decoded = UE.GetString(ms.ToArray());

    Es decir, suponiendo que la imagen se haya salvado originalmente en binario dentro del fichero, entonces después de decodificarlo quieres recuperar el binario. NO quieres convertirla en un string, que no te serviría para poderla mostrar en un picturebox.

    Para pasarla desde el MemoryStream al picturebox, primero se pasa a un objeto Image, que precisamente dispone de un método para leer desde un Stream:

    Image img = Image.FromStream(ms);

    Y luego ya se la puedes asignar al picturebox:

    pictureBox1.Image = img;

    viernes, 8 de marzo de 2019 11:56
    Moderador
  • hago mi esfuerzo ya que no se mucho de este codigo, ya no se que mas hacer este es un ejemplo de como podria funcionar pero no funciona

    this.pictureBox1.BackgroundImage = Common.DecryptFile2("copia2.png");

    public static string DecryptFile2(string inputFile)
    {
                string password = @"myKey123"; // Your Key Here
                string decoded = string.Empty;
                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password);
        {
                    using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
                    {
                        using (RijndaelManaged RMCrypto = new RijndaelManaged())
                        {
                            CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read);
                            using (MemoryStream ms = new MemoryStream())
                            {
                                int data;
                                while ((data = cs.ReadByte()) != -1)
                                    ms.WriteByte((byte)data);

                                if (ms.CanSeek)
                                    ms.Seek(0, SeekOrigin.Begin);

                                decoded = UE.GetString(ms.ToArray());
                                //System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

                                //Globals.pForm.pictureBox1.Image = img;
                            }
                        }
                    }
        }
                return decoded;
       }

    viernes, 8 de marzo de 2019 16:30
  • No, claro que no te funciona. Fíjate que te puse buen claro en la respuesta que a la imagen no le puedes poner un string, sino que requiere la imagen en binario. Pero no has cambiado nada en el método, sigues teniendo un string por todas partes.

    En la declaración del método dices:

    public static string DecryptFile2(...)

    Comprendo que no seas muy experto programando, pero tus conocimientos deberían ser al menos suficientes para darte cuenta de que eso está devolviendo un string.

    Por lo tanto no es lícito hacer:

    this.pictureBox1.BackgroundImage = Common.DecryptFile2(...);

    porque si el Common.DecryptFile2 devuelve un string no se puede meter dentro del BacgroundImage que NO es de tipo string.

    Tendrías que cambiarlo de manera consistente; lo que menos complicaciones te ocasionará es devolver un Image en lugar del string, y entonces se lo puedes asignar al this.pictureBox1.BackgroundImage.

    Quita la linea decoded = UE.GetString(ms.ToArray()); y en su lugar pon

    return System.Drawing.Image.FromStream(ms);

    Y después de eso haz limpieza y suprime todos los sitios donde usas la variable decoded, que ya no se usa.


    viernes, 8 de marzo de 2019 17:13
    Moderador
  • use dos metodos pero con el mismo resultado

    primer metodo

    BackgroundImage = Common.DecryptFile2("copia2.png"); ;

    codigo 

    public static System.Drawing.Image DecryptFile2(string inputFile)
    {
                string password = @"myKey123"; // Your Key Here
                //string decoded = string.Empty;
                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password);
        {
                    using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
                    {
                        using (RijndaelManaged RMCrypto = new RijndaelManaged())
                        {
                            CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read);
                            using (MemoryStream ms = new MemoryStream())
                            {
                                int data;
                                while ((data = cs.ReadByte()) != -1)
                                    ms.WriteByte((byte)data);

                                if (ms.CanSeek)
                                    ms.Seek(0, SeekOrigin.Begin);

                                return System.Drawing.Image.FromStream(ms);


                                //decoded = UE.GetString(ms.ToArray());
                            }
                        }
                    }
        }
                //return decoded;
       }

    resultado la imagen no carga y en su lugar aparece eso

    segundo codigo haciendo una convercion string a image

    string bArr = Common.DecryptFile2("copia2.png");
                Image img1 = stringArrayToImage(bArr);
                BackgroundImage = img1;

    public Image stringArrayToImage(string inputString)
            {
                byte[] imageBytes = System.Text.Encoding.Unicode.GetBytes(inputString);
                System.IO.MemoryStream ms = new System.IO.MemoryStream(imageBytes, 0, imageBytes.Length);

                ms.Write(imageBytes, 0, imageBytes.Length);
                Image image = Image.FromStream(ms, true, true);

                return image;
            }

    public static string DecryptFile2(string inputFile)
    {
                string password = @"myKey123"; // Your Key Here
                string decoded = string.Empty;
                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password);
        {
                    using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
                    {
                        using (RijndaelManaged RMCrypto = new RijndaelManaged())
                        {
                            CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read);
                            using (MemoryStream ms = new MemoryStream())
                            {
                                int data;
                                while ((data = cs.ReadByte()) != -1)
                                    ms.WriteByte((byte)data);

                                if (ms.CanSeek)
                                    ms.Seek(0, SeekOrigin.Begin);

                                decoded = UE.GetString(ms.ToArray());
                                
                            }
                        }
                    }
        }
                return decoded;
       }

    resultado

    viernes, 8 de marzo de 2019 17:28
  • Cuando esto te ocurra y te salga un error, a la hora de preguntar en el foro es importante dar todos los detalles posibles porque la gente que está leyendo el mensaje en el foro no puede tomar control de tu ordenador y examinar la información proporcionada por el debugger. En el mensaje de "excepción no controlada" es importante pulsar en "detalles" porque te muestra la traza de pila e indica la excepción que se produjo. También es importante usar el debugger en Visual Studio para señalar la línea de código exacta en la que ocurre el error.

    Dicho eso, y suponiendo que la línea en la que ocurre es la que construye el Image a partir del Stream (y digo "suponiendo" porque no se puede ver en la imagen que has puesto), entonces lo más probable es que el error de "memoria insuficiente" se deba a que le estamos asignando en el Image unos datos binarios que no representan un formato de imagen reconocido. Esto se puede deber a un error en la rutina de desencriptación, que indicaría que no estamos descifrando los bytes con el algoritmo correcto (el mismo que se usó al cifrarla).

    Para verificar esto, lo ideal sería partir de una imagen conocida. Como primera precaución, abrirla en el picturebox para cerciorarse de que es un formato compatible. Después, aplicar el procedimiento de cifrado para pasarla al fichero cifrado. Después, descifrarlo usando el mrimer método (el que la salvaba a un archivo) y abrir ese archivo para comprobar que el algoritmo es correcto y que puede cifrar y descifrar sin corromperla. Si todo eso va bien, entonces pasamos a usar el método del MemoryStream. Lo ejecutamos con el debugger y examinamos los primeros bytes que nos devuelve. Los comparamos con el fichero original de partida (por ejemplo, abriéndolo con un editor binario) y verificamos que coinciden exactamente. Si no coinciden, algo está mal en el algoritmo de descifrado. Si coinciden, algo está mal en la conversión a Image. De esta manera, vamos paso a paso siguiendo todo el circuito para localizar dónde puede estar el problema.

    viernes, 8 de marzo de 2019 19:18
    Moderador
  • el error que tenia era por que no tenia 

    ms.Dispose();

    sin embargo aun sigo sin resolverlo

    sábado, 9 de marzo de 2019 2:41
  • No, la falta del Dispose() no haría que fallase, solo ocasionaría que vayas consumiendo recursos poco a poco si lo ejecutas muchas veces.

    Si sigues sin resolverlo, ponnos aquí el resultado y las observaciones de cada una de las pruebas que te sugerí antes, y así podemos centrar dónde está el problema.

    sábado, 9 de marzo de 2019 9:42
    Moderador