Reputation: 661
I made a Encryption program using Rijndael in C# after watching a video in youtube.It's very simple.
Interface picture I can enter 64 bit and 128 bit keys. but 192 bit keys are not allowed (Why? ).
And if I use 64 bit key, when I encrypt a word and try to decrypt it back it only decrypts word with character count <= 16. it the character count is more than 16 an error messages thrown saysing "Padding is Invalid and cannot be removed".
Same goes for a 128 bit key. Only word with character count <=32 is decrypted back. otherwise same error message is displayed.
Here's a summery to take a clear view of the question
Problem Summery picture Here's the code for Encryption
// need using System.Security.Cryptography;
// using System.IO;
public Form1()
{
InitializeComponent();
desObj = Rijndael.Create();
}
string cipherData;
byte[] chipherbytes;
byte[] plainbyte;
byte[] plainbyte2;
byte[] plainkey;
SymmetricAlgorithm desObj;
private void button2_Click(object sender, EventArgs e)
{
try
{
cipherData = textBox1.Text;
plainbyte = Encoding.ASCII.GetBytes(cipherData);
plainkey = Encoding.ASCII.GetBytes(textBox4.Text);
desObj.Key = plainkey;
//choose any method
desObj.Mode = CipherMode.CBC;
desObj.Padding = PaddingMode.PKCS7;
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, desObj.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(plainbyte, 0, plainbyte.Length);
cs.Close();
chipherbytes = ms.ToArray();
ms.Close();
textBox2.Text = Encoding.ASCII.GetString(chipherbytes);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
and the decyption code is
private void button3_Click(object sender, EventArgs e)
{
try
{
MemoryStream ms1 = new MemoryStream(chipherbytes);
CryptoStream cs1 = new CryptoStream(ms1, desObj.CreateDecryptor(), CryptoStreamMode.Read);
cs1.Read(chipherbytes, 0, chipherbytes.Length);
plainbyte2 = ms1.ToArray();
cs1.Close();
ms1.Close();
textBox3.Text = Encoding.ASCII.GetString(plainbyte2);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Upvotes: 1
Views: 608
Reputation: 61902
Ciphertext consists of arbitrary bytes which do not have to make up a valid ASCII encoding. If there are some non-printable ASCII characters, they will not be printed when used in this way: Encoding.ASCII.GetString(chipherbytes)
.
You need to encode the ciphertext with something like Base64 or Hex which will make the encoded ciphertext larger, but is perfectly representable as a printed string.
Other considerations:
CBC mode needs an initialization vector (IV) and since you're not setting any IV, it will be generated for you. The problem is that you need the same IV during decryption. This code works, because you're using the same desObj
for encryption and decryption and it contains the same IV, but that's not going to work when you start copying ciphertext around.
The IV is not supposed to be secret. A common way is to pass it along with the ciphertext by writing the IV in front of it and slicing it off before decryption.
You're not having any integrity checking. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible and you can detect whether the ciphertext was (maliciously) tampered with or the key was typed in incorrectly. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.
Rijndael commonly supports key sizes of 128, 192 and 256 bit. A byte usually has 8 bits, so that amounts to 16, 24 and 32 byte keys.
Keys are not typed in by the user, because they usually need to be indistinguishable from random noise and of specific length. It is better to let users type in a password and derive the key from that with something like PBKDF2, bcrypt, scrypt or Argon2 using a high iteration count / cost factor.
Upvotes: 0