So I'm trying to encrypt / decrypt a word document using a Caesar cipher shift. My Caesar class works for images(.png) and (.txt) documents. However when I encrypt a word document (.docx) and decrypt that word document again the last byte get's modified. The following picture shows what I mean:
All but the last byte get changed correctly. Instead of a NUL byte the modified document contains an SOH byte which is apparently a "Start of Header".
This is my caeser cipher class containing the enciper and decipher function:
static char ciphChar(char ch, int key)
{
if (!char.IsLetter(ch))
{
return ch;
}
char d = char.IsUpper(ch) ? 'A' : 'a';
return (char)((((ch + key) - d) % 26) + d);
}
public static string Cipher(string message, int key, bool cipherMode)
{
if (cipherMode == false)
{
key = 26 - key;
}
string output = string.Empty;
foreach (char ch in message)
output += ciphChar(ch, key);
return output;
}
The encipher & decipher functions are also below (the Caeser cipher shifts the message by the number from the key. So for example if the message is 'a' and the key is 3, the message becomes 'd', because 'a' shifted 3 letters across the alphabet is 'd'):
public static string Encipher(string input, int key)
{
return Cipher(input, key, true);
}
public static string Decipher(string input, int key)
{
return Cipher(input, key, false);
}
To use the encipher function on a document I convert the document bytes to a string using Convert.ToBase64String
. After I read in the bytes as a string I use my enciphe / deciphe function and convert the string back to bytes using the following code Convert.FromBase64String
.
My code successfully encrypts & decrypts .txt files and .png files. However for .docx files the last byte doesn't decode back correctly.. I appreciate any guidance to solve my problem, thanks.
Edit 1: I've added some code so you can reconstruct the problem i'm dealing with.
Create a class called caesarShift and copy the code from the caesar cipher and enciper/decipher functions written above in my original post.
Create a main form with 3 buttons and 1 textbox. Copy the following code below:
public static byte[] EncryptFile(string filePath) { byte[] fileBytes = File.ReadAllBytes(filePath); byte[] bytesEncrypted = Enciphe(fileBytes); File.WriteAllBytes(filePath, bytesEncrypted); return bytesEncrypted; } public static byte[] DecryptFile(string filePath) { byte[] fileBytes = File.ReadAllBytes(filePath); byte[] bytesDecrypted = Deciphe(fileBytes); File.WriteAllBytes(filePath, bytesDecrypted); return bytesDecrypted; } static byte[] Enciphe(byte[] file) { var fileToString = Convert.ToBase64String(file); string caeser; caeser = caesarShift.Encipher(fileToString, 3); file = Convert.FromBase64String(caeser); return file; } static byte[] Deciphe(byte[] file) { var fileToString = Convert.ToBase64String(file); string caeser; caeser = caesarShift.Decipher(fileToString, 3); file = Convert.FromBase64String(caeser); return file; } private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.Filter = "encryptable files|*.rtf;*.docx;*.jpg;*.txt;*.png;"; openFileDialog1.Title = "Select File"; if (Directory.Exists(textBox1.Text)) { openFileDialog1.InitialDirectory = textBox1.Text; } else { openFileDialog1.InitialDirectory = @"C:\"; } if (openFileDialog1.ShowDialog() == DialogResult.OK) { textBox1.Text = openFileDialog1.FileName; } } private void button2_Click(object sender, EventArgs e) { EncryptFile(textBox1.Text); } private void button3_Click(object sender, EventArgs e) { DecryptFile(textBox1.Text); }
- Create a dummy word document and test the encrypt / decrypt function. You can also test .jpg and .txt files (they are working).