¿Por qué RijndaelManaged devuelve datos basura después del cifrado?

He tomado el código de descifrado de http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream.aspx y lo modificó de la siguiente manera a continuación. Tengo un ejemplo encriptado y funciona bien durante la decodificación. Pero cuando usa la función de cifrado, devuelve una cadena basura con símbolos extraños. a continuación se encuentran las funciones de encriptar/desencriptar.

Un ejemplo de cadena encriptada "hey": "???U?b???z?Y???"
Cuando se decodifica de nuevo: "ûc{ÁpÅ`ñ""Â"

Estoy usando este código para convertir la matriz de bytes en una cadena:

private string ByteArrayToString(byte[] input)
    {
        ASCIIEncoding dec = new ASCIIEncoding();
        return dec.GetString(input);
    }

aquí están las funciones de encriptar/desencriptar. la función de descifrado funciona bien.

private string DecryptStringFromBytesAes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the string used to hold 
        // the decrypted text.
        string plaintext = null;

        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged aesAlg = new RijndaelManaged())
        {
            aesAlg.Key = Key;
            aesAlg.Padding = PaddingMode.Zeros;
            aesAlg.Mode = CipherMode.ECB;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }

        }

        return plaintext;

    }




private byte[] EncryptStringToBytesAes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged aesAlg = new RijndaelManaged())
        {
            aesAlg.Key = Key;
            aesAlg.Padding = PaddingMode.Zeros;
            aesAlg.Mode = CipherMode.ECB;
            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption. 
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        return encrypted;

    }

preguntado el 27 de julio de 12 a las 16:07

Bueno, el objetivo principal de cualquier proceso de encriptación es convertir algunos datos significativos en algo que parezca basura. Cuanto más parece basura, mejor es el algoritmo de cifrado. -

Cuando dice que la función de encriptación devuelve un código basura, ¿quiere decir que devuelve una cadena cifrada que se verá como basura? :-) Las cadenas encriptadas siempre se verán "raras" -

sí, devuelve cadenas como ???? y cuadrados también -

jajaja, eso es encriptación para ti. Podrías codificarlo en base64 para deshacerte de los feos caracteres que no se imprimen. -

3 Respuestas

Lo que observa es el problema de mapear bytes arbitrarios (en el rango 0-255) a caracteres. Los caracteres significativos solo están en el rango 32-255 o incluso solo 32-127 (ASCII). Los valores por debajo de 32 son los denominados caracteres no imprimibles y los valores por encima de 127 dependen de la codificación de caracteres que esté utilizando. Es por eso que el texto encriptado parece basura. Por lo tanto, los sistemas criptográficos de mástil transforman los bytes en el rango ASCII sensible. Uno de esos algoritmos es BASE64. Así que manipular los bytes encriptados a través de BASE64 da caracteres que son todos imprimibles y que se enviarán sin problemas a través del correo electrónico. Antes de descifrar, debe deshacer la codificación BASE64.

Otra forma de hacer que el resultado cifrado se vea mejor es mostrar su representación hexadecimal. Por ejemplo, si tiene un valor de byte de 15 tu imprimes 0F. Puede usar esto para representar su matriz de bytes en hexadecimal:

private string ByteArrayToHexString(byte[] data)
{
    return String.Concat(data.Select(b => b.ToString("x2")));
}

Respondido 27 Jul 12, 16:07

Esto es correcto. Solo para aclarar a los lectores desprevenidos, la codificación Base64 es codificación y no criptografía. Es una forma de almacenar binarios en el rango ASCII. - Jodrell

sí, base64 es una solución, pero el comentario de Jesse C. Slicer es exactamente lo que necesitaba. - cprogcr

Para tener su salida como una codificación hexadecimal de los datos, siga los métodos encontrados aquí. Los modifiqué ligeramente para que fueran métodos de extensión:

    public static string ToHexString(this byte[] bytes)
    {
        return bytes == null ? string.Empty : BitConverter.ToString(bytes).Replace("-", string.Empty);
    }

    public static byte[] FromHexString(this string hexString)
    {
        if (hexString == null)
        {
            return new byte[0];
        }

        var numberChars = hexString.Length;
        var bytes = new byte[numberChars / 2];

        for (var i = 0; i < numberChars; i += 2)
        {
            bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
        }

        return bytes;
    }

contestado el 23 de mayo de 17 a las 13:05

Las cadenas cifradas parecerán distorsionadas. La forma de probar si el cifrado funciona correctamente es pasar su cadena de nuevo a través del descifrado. Si funciona en el descifrado, sabrá que la cadena es correcta a pesar de que le parezca basura.

Respondido 27 Jul 12, 16:07

las cadenas encriptadas deben verse así: cfdece55b562efeeb37aa459a013dab3 en su lugar tienen símbolos extraños como ?? y cuadrados - cprogcr

Depende del cifrado utilizado. Su número anterior parece un hash y no un valor encriptado. Intentaría cifrar y luego usar el descifrado y ver si obtiene su valor original. Si lo hace, puede ser simplemente un problema de codificación de caracteres en su editor que cambia la forma en que ve la cadena cifrada. Utilice la codificación base 64. - Shawn

@cprogcr Por lo tanto, desea una salida hexadecimal en lugar de los bytes cifrados reales. Ver stackoverflow.com/a/311179/3312 sobre cómo convertir hacia y desde esta notación. - Jesse C. Rebanadora

@JesseC.Slicer escríbalo como respuesta para que pueda marcarlo como resuelto :) Funcionó por cierto - cprogcr

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.