-1

I have used Rijndael Algorithm for Encryption and decryption.

The Decryption works fine when i do it with Encryption.

But when i try to do Decryption alone it returns something like this

J˿m"�e��c4�ħ�dB̵��Dq@W�.

Also i have used two buttons one is for encryption and another one is for decryption and called the methods when button clicks.

I cannot able to get any idea regarding why the output is returning like this. Even i used same convertion(UTF8 Encoding) for both methods.

Please help me to solve this problem.

Below is my code:

public partial class Form1 : Form
{
    private RijndaelManaged myRijndael = new RijndaelManaged();
    private int iterations;
    private byte [] salt;

    public Form1(string strPassword)
    {
        myRijndael.BlockSize = 128;
        myRijndael.KeySize = 128;
        myRijndael.IV = HexStringToByteArray("e84ad660c4721ae0e84ad660c4721ae0");

        myRijndael.Padding = PaddingMode.PKCS7;
        myRijndael.Mode = CipherMode.CBC;
        iterations = 1000;
        salt = System.Text.Encoding.UTF8.GetBytes("cryptography123example");
        myRijndael.Key = GenerateKey(strPassword);
    }

    public string Encrypt(string strPlainText)
    {
        byte[] strText = new System.Text.UTF8Encoding().GetBytes(strPlainText);
        MemoryStream ms = new MemoryStream();
        ICryptoTransform transform = myRijndael.CreateEncryptor();
        CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write); 
        cs.Write(strText, 0, strText.Length);

        cs.FlushFinalBlock();
        return Convert.ToBase64String(ms.ToArray());
    }

    public string Decrypt(string encryptedText)
    {
        var encryptedBytes = Convert.FromBase64String(encryptedText);
        MemoryStream ms = new MemoryStream();
        ICryptoTransform transform = myRijndael.CreateDecryptor();
        CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
        cs.Write(encryptedBytes, 0, encryptedBytes.Length);

        return System.Text.Encoding.UTF8.GetString(ms.ToArray());
    }

    public static byte[] HexStringToByteArray(string strHex)
    {
        dynamic r = new byte[strHex.Length / 2];
        for (int i = 0; i <= strHex.Length - 1; i += 2)
        {
            r[i / 2] = Convert.ToByte(Convert.ToInt32(strHex.Substring(i, 2), 16));
        }
        return r;
    }

    private byte[] GenerateKey(string strPassword)
    {
        Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(System.Text.Encoding.UTF8.GetBytes(strPassword), salt, iterations);
        return rfc2898.GetBytes(128 / 8);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EncryptOutput.Text = Encrypt(EncryptInput.Text);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        DecryptOutput.Text = Decrypt(DecryptInput.Text);
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
preethi
  • 7
  • 1

2 Answers2

1

Try this code:

public string Encrypt(string strPlainText) {
    byte[] strText = System.Text.Encoding.UTF8.GetBytes(strPlainText);

    using (ICryptoTransform encryptor = myRijndael.CreateEncryptor())
    using (MemoryStream input = new MemoryStream(strText))
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) {
        input.CopyTo(cs);
        cs.FlushFinalBlock();
        return Convert.ToBase64String(output.GetBuffer(), 0, (int)output.Length);
    }
}

public string Decrypt(string encryptedText) {
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);

    using (ICryptoTransform decryptor = myRijndael.CreateDecryptor())
    using (MemoryStream input = new MemoryStream(encryptedBytes))
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(input, decryptor, CryptoStreamMode.Read)) {
        cs.CopyTo(output);
        return System.Text.Encoding.UTF8.GetString(output.GetBuffer(), 0, (int)output.Length);
    }
}

public static byte[] HexStringToByteArray(string strHex) {
    var r = new byte[strHex.Length / 2];

    for (int i = 0; i < strHex.Length; i += 2) {
        r[i / 2] = byte.Parse(strHex.Substring(i, 2), NumberStyles.HexNumber);
    }
    return r;
}

Please, remember using the using pattern... And dynamic should be used only in very special cases.

Note that the Encrypt is doable with one less Stream, in a very similar way to the one you wrote it:

public string Encrypt(string strPlainText) {
    byte[] strText = System.Text.Encoding.UTF8.GetBytes(strPlainText);

    using (ICryptoTransform encryptor = myRijndael.CreateEncryptor())
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) {
        cs.Write(strText, 0, strText.Length);
        cs.FlushFinalBlock();
        return Convert.ToBase64String(output.GetBuffer(), 0, (int)output.Length);
    }
}

but the Decrypt needs two Stream, because the CryptoStream needs a Stream as a parameter, containing the encrypted data, and it is easier to write its output (of which you don't know the exact lenth, thanks to padding) to another stream.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Thanks for the reply.i have tried executing the above code and it shows error in the line cs.CopyTo(output); that "Padding is invalid and cannot be removed".please help me – preethi Mar 15 '16 at 09:46
  • @preethi Are you encrypting and decrypting with that functions? Because the padding must be the same for encryption and decryption. – xanatos Mar 15 '16 at 09:48
  • That code works for me, my fixed code works for me. They both give the same errors for you. So you must have changed your code locally from what you pasted. – zeromus Mar 15 '16 at 09:53
  • @preethi As they say... It works on my pc... and even on ideone: https://ideone.com/agnOqS ... – xanatos Mar 15 '16 at 09:53
  • Decryption working for me when i do it with Encryption.But when i paste the encrypted data into decryption input box and click the decrypt button it shows "Padding is invalid and cannot be removed".I want to execute the decryption alone.Please help me.Also i didnt change anything in my code locally. – preethi Mar 15 '16 at 10:07
  • @preethi Are you sure you are pasting all the base64 text? It is quite strange. Try puttign a breakpoint in the `DecryptOutput.Text = Decrypt(DecryptInput.Text);` line and take a look at the `DecryptInput.Text` – xanatos Mar 15 '16 at 10:10
  • @ xanatos i have inserted breakpoint int that line and tried encryption & decryption works fine..when i try decryption alone it pointing error in both lines cs.CopyTo(output); return System.Text.Encoding.UTF8.GetString(output.GetBuffer(), 0, (int)output.Length); as "Padding is invalid and cannot be removed"..it works well with encryption but why dont it work without it?Please give me some idea.thank you – preethi Mar 15 '16 at 11:11
0

cs.FlushFinalBlock(); forgotten in Decrypt()? I just round-tripped a test string with your code once I fixed that

zeromus
  • 1,648
  • 13
  • 14
  • Thanks for the reply.when i try to add cs.FlushFinalBlock(); in decryption,it shows error message like "Padding is invalid and cannot be removed." – preethi Mar 15 '16 at 09:37
  • I've had an epiphany. When you say "decryption alone" you mean you're trying to decrypt a string encrypted by someone else. Someone else..with different settings. Just google that error message: http://stackoverflow.com/questions/8583112/padding-is-invalid-and-cannot-be-removed ; use the same settings as someone else. – zeromus Mar 15 '16 at 13:52
  • i have encrypted the code using same application,close and restart it again and pasting the same encrpted code in decryptioninput box and when i try click decrypt button,it shows the error message. – preethi Mar 16 '16 at 04:27
  • no such problem here, just tried it. you must still have a difference in your code you havent pasted – zeromus Mar 16 '16 at 05:55
  • @zeromus.i have captured video for the issue which am facing.please have a look on this file ( https://www.dropbox.com/s/zs6q0zhyf29n6o0/Rijndael.rar?dl=0 ) .Please help me to sort out this. – preethi Mar 16 '16 at 07:17
  • "you must still have a difference in your code you haven't pasted".You're not using the code @xanatos gave you. You're not using the code you originally posted. You're using his decrypt and your encrypt. Use his 0% of your code if you're tired of having bugs in your 100% of your code and your 50% of your code – zeromus Mar 16 '16 at 07:53