BinaryRead / Write / FileStream.Read/Write /File.Read/WriteAllBytes后文件损坏

时间:2014-04-16 07:26:23

标签: c# encryption cryptography

我正在进行文件加密/解密应用并长时间停留。 我无法相信读取和写入文件会很困难。

这是变量

    byte[] FileBytes = null; //file bytes
    byte[] KeyBytes = null; //key bytes
    byte[] ResBytes = null; //result bytes

从文件中读取所有字节

    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();
        }
    }

写文件

    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();
        }
    }

加密方法

    public byte ApplyVernam(byte inByte, byte keyByte)
    {
        if (inByte == keyByte) { return inByte; }
        else { return (byte)(inByte ^ keyByte); }
    }

这里是执行按钮点击事件(我把FileBytes [1]作为键),是的,除文本文档外,文件已损坏。我认为BinaryWriter很适合进行文件加密,但为什么它不起作用?我的代码出了什么问题? 我在这里需要解释。 非常感谢你。

    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;
        }
    }

1 个答案:

答案 0 :(得分:2)

您的加密方法不可逆,因此您无法使用它可靠地解密常规二进制消息。出现此问题是因为可能会将两个不同的明文值加密到相同的密文值,并且当发生这种情况时,您无法确定何时解密哪个是正确的输入值。

示例:

if inByte = 100 and keyByte = 100:
    ApplyVernam(100, 100) = 100

if inByte = 0, keyByte = 100:
    ApplyVernam(0, 100) = 100

在尝试解密时,现在无法判断原始明文字节是0还是100

我建议您从if (inByte == keyByte) { return inByte; }方法中删除该行:ApplyVernam,以便始终XORs输入密钥,因此完全可逆。

正如我的评论所述,你的&#34;键&#34;是输入中位置1的字节,但这也是加密的,因此当您解密时,位置1的字节不再是原始密钥。更改以下行可能会解决此问题:

自:

this.ResBytes[x] = this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);

要:

this.ResBytes[x] = x == 1 ? this.FileBytes[x] : this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);

这将确保密钥字节未加密写入输出。