Reputation: 55
I'm doing file encrypt/decrypt application and stuck for a long time. I can't believe it gonna be this hard just to read and write files.
Here's the variable
byte[] FileBytes = null; //file bytes
byte[] KeyBytes = null; //key bytes
byte[] ResBytes = null; //result bytes
Read all bytes from the file
private void ReadFile()
{
using (BinaryReader br = new BinaryReader(File.Open(this.txtFilePath.Text, FileMode.Open, FileAccess.Read)))
{
int x = 0;
this.FileBytes = new byte[(int)br.BaseStream.Length];
int length = (int)br.BaseStream.Length;
while (x < length)
{
this.FileBytes[x] = br.ReadByte();
x++;
}
br.Close();
}
}
Write the file
private void WriteFile()
{
using (BinaryWriter bw = new BinaryWriter(File.Open(this.OutputPath, FileMode.Create)))
{
// 3. Use foreach and write all 12 integers.
foreach (byte b in this.ResBytes)
{
bw.Write(b);
}
bw.Flush();
bw.Close();
}
}
Encryption method
public byte ApplyVernam(byte inByte, byte keyByte)
{
if (inByte == keyByte) { return inByte; }
else { return (byte)(inByte ^ keyByte); }
}
And here's the execute button click event (I put FileBytes[1] as key) and yes, the file corrupted except for text document. I thought BinaryWriter is good to do file encryption, but why it's not working? Something wrong in my code? I need explanation here. Thank you very much.
private void btnExecute_Click(object sender, EventArgs e)
{
try
{
this.ReadFile();
this.ResBytes = new byte[this.FileBytes.Length];
int x = 0;
while (x < this.FileBytes.Length)
{
this.ResBytes[x] = this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);
x++;
}
this.WriteFile();
}
catch
{
throw;
}
}
Upvotes: 0
Views: 1479
Reputation: 23721
Your encryption method is not invertible, and so you cannot reliably decrypt a general binary message with it. The problem occurs because it is possible for two different plaintext values to encrypt to the same ciphertext value, and when this happens there's no way for you to determine when decrypting which was the correct input value.
Example:
if inByte = 100 and keyByte = 100:
ApplyVernam(100, 100) = 100
if inByte = 0, keyByte = 100:
ApplyVernam(0, 100) = 100
It's now impossible to tell whether the original plaintext byte was 0
or 100
when trying to decrypt.
I would suggest removing the line: if (inByte == keyByte) { return inByte; }
from your ApplyVernam
method so that it always XORs
the input with the key and so is fully invertible.
As mentioned in my comment, your "key" is the byte at position 1 in the input, but this is also being encrypted, and so when you decrypt, the byte at position 1 is no longer the original key. Changing the following line may resolve the issue:
From:
this.ResBytes[x] = this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);
To:
this.ResBytes[x] = x == 1 ? this.FileBytes[x] : this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);
This will ensure that the key byte is written unencrypted to the output.
Upvotes: 2