0

I started out by using ECB because I heard that it was the easiest to begin with so I created a console application that accepted input to encrypt and then would decrypt it and output both the encrypted text and the decrypted text. That all worked perfectly. I went to try and use CBC created a new program from scratch and I am getting an error: "Padding is invalid and cannot be removed." From what I can see I have done everything correctly, can anyone point me in the right direction on what my problem may be? Ive tried everything I can find on blogs and on this site to no avail. The exception is occurring at the line: DecryptedText = srDecrypt.ReadToEnd() in the DecryptData Method.

RijndaelManaged rijm = new RijndaelManaged();
//more variables here

    protected void Page_Load(object sender, EventsArgs e)
    {
        //Convert Key from string to Byte Array Here

        rijm.BlockSize = 128;
        rijm.KeySize = 256;
        rijm.Key = keyByteArray;
        rijm.Mode = CipherMode.CBC;
        rijm.Padding = PaddingMode.PKCS7;
        ICryptoTransform crypt = rijm.CreateEncryptor(keyByteArray, null);

        using(crypt)
        {
           byte[] value1Cipher = EncryptData(crypt, value1);
           byte[] value2Cihper = EncryptData(crypt, value2);

           encryptedValue1 = Convert.ToBase64String(vaue1Cipher);
           encrpytedValue2 = Convert.ToBase64String(value1Cipher);
        }

        ICryptoTransform decrypt = rijm.CreateDecryptor(keyByteArray, null);

        using (decrypt)
        {
           decryptedValue1 = DecryptData(decrypt, encryptedValue1); //string
           decryptedValue2 = DecryptData(decrypt, encrpytedValue2); //string
        }
        //... Do something with the values here.
    }
    private byte[] EncryptData(ICryptoTransform encrypt, string text)
    {
        var stream = new MemoryStream();
        using (var cryptoStream = new CryptoStream(stream, encrypt, CryptoStreamMode.Write))
        {
            using (var writer = new StreamWriter(cryptoStream))
            {
                writer.Write(text);

            }
        }
        return stream.ToArray();
    }

    private string DecryptData(ICryptoTransform decrypt, string cipherText)
    {
        string decryptedText = null;
            byte[] text = Convert.FromBase64String(cipherText);
            using (MemoryStream msDecrypt = new MemoryStream(text))
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decrypt, CryptoStreamMode.Read))
            using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                decryptedText = srDecrypt.ReadToEnd();

        return decryptedText;
    }
ios85
  • 2,104
  • 7
  • 37
  • 55
  • @JonWillemse I already tried that and it had no affect. – ios85 May 31 '13 at 12:54
  • On which line do you get the exception? – John Willemse May 31 '13 at 12:57
  • @JohnWillemse it occurs at the line decryptedText = srDecrypt.ReadToEnd() in the DecryptData Method. – ios85 May 31 '13 at 12:59
  • I see a mistake in these lines: `decryptedValue1 = DecryptData(decryptor, ...`, where I think `decryptor` should read `decrypt`, but not sure if that's just a typo or related. – John Willemse May 31 '13 at 13:03
  • @JohnWillemse That was just a mistake by me when I was cleaning up the code to put on the site. Thanks for catching that though so its more clear now. – ios85 May 31 '13 at 13:12

1 Answers1

1

Either use the no parameter CreateEncryptor()/CreateDecryptor() methods, or pass an IV. If you use the no-param versions, you should call CreateIV and store off the resulting value in .IV.

Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
  • So ECB doesnt require an IV, but CBC does? – ios85 May 31 '13 at 13:23
  • Correct - ECB doesn't use an IV (it's kind of impossible to fit into the ECB scheme, which treats each block independently). CBC uses the IV to encrypt the first block. The API is the same (and not all that well documented) so it can get confusing. – Mark Brackett May 31 '13 at 13:35