C#AES解密总是以10个字节的杂乱代码结束。

时间:2017-04-20 08:10:10

标签: c# encryption cryptography

我有一个文本文件" toEnc.txt" (文件大小为485b)进行加密和解密。

加密后," byte [] enc_data"的长度增加到496b 但是我已经设置了" enc.Padding = PaddingMode.None;"

解密后,无论文本内容是什么," testout.txt"最后总是有10个字节的乱码。

我也试过.zip文件。加密文件长度也增加了,解密文件在解密后被破坏了(可能是因为zip文件末尾有一些奇怪的杂乱代码)。

这是我的代码:

       private async Task RunEncryption()
       {
           String data;
           using (StreamReader sr = new StreamReader("toEnc.txt"))
           {
              data = sr.ReadToEnd();
           }
           byte[] enc_data = await Program.myEncrypt(data);

            await RunDecrypt(enc_data);   //to test if decryption works
      }

    static async Task<byte[]> myEncrypt(string toEncStr)
    {
        byte[] encrypted;
        using (Aes enc = Aes.Create())
        {
            Aes encaes = Aes.Create();
            encaes.Key = enc.Key;
            encaes.IV = enc.IV;

            Program.Key = enc.Key;
            Program.IV = enc.IV;

            try
            {
                FileStream fs = new FileStream("key.txt", FileMode.OpenOrCreate);
                fs.Write(Key, 0, Key.Length);
                fs.Write(IV, 0, IV.Length);
                fs.Close();
            }
            catch ( Exception e)
            {
                Console.WriteLine("Encryption failed!{0}.", e.Message);
                Environment.Exit(0);
            }

            enc.Padding = PaddingMode.None;

            ICryptoTransform encryptor = encaes.CreateEncryptor(encaes.Key, encaes.IV);

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(toEncStr);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        return encrypted;
    }

    private async Task RunDecrypt(byte[] inbytes)
    {
        try
        {
            String write_data = await myDecrypt(inbytes);
            using (StreamWriter sw = new StreamWriter("testout.txt", true))
            {
                sw.Write(write_data);
                sw.Close();
            }
        }
        catch (Exception e)
        {

        }
    }
    async Task<String> myDecrypt(byte[] toDecBytes)
    {
        try
        {
            String decrypted;
            using (Aes dec = Aes.Create())
            {
                byte[] Key = new byte[dec.Key.Length];
                byte[] IV = new byte[dec.IV.Length];
                FileStream fsread = new FileStream("key.txt", FileMode.Open);
                fsread.Read(Key, 0, Key.Length);
                fsread.Read(IV, 0, IV.Length);
                fsread.Close();

                dec.Key = Key;
                dec.IV = IV;

                dec.Padding = PaddingMode.None;
                ICryptoTransform decryptor = dec.CreateDecryptor(dec.Key, dec.IV);
                using (MemoryStream msDecrypt = new MemoryStream(toDecBytes))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            decrypted = srDecrypt.ReadToEnd();
                            //decrypted = srDecrypt.Read(  , 0, );
                            return decrypted;
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Decryption failed! {0}.", e.Message);
            return @"null";
        }
    }

1 个答案:

答案 0 :(得分:2)

您的代码存在许多问题。

  • 如果您使用PaddingMode.None,则必须提供明确 块大小的倍数的明文(AES为16个字节)。因此,您将无法简单地加密任意明文。请使用PaddingMode.Pkcs7进行加密和解密。

  • 在完全写入之前,您正在读取密文。 encrypted = msEncrypt.ToArray();阻止后,您需要致电using (CryptoStream csEncrypt...

    using (MemoryStream msEncrypt = new MemoryStream())
    {
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
            {
                swEncrypt.Write(toEncStr);
            }
        }
        encrypted = msEncrypt.ToArray();
    }
    
  • 您有太多可用于加密的变量。您只需要一个Aes实例(enc)。只需使用encaesProgram丢弃代码,然后从Key实例中写出正确的IVenc

IV不是秘密,因此您可以将其与密文一起发送。通常,它只是在密文之前预先填写并在解密之前切掉。